2011-02-04 53 views
0
void doWork(){ 

    int fd[2]; 
    int pret = pipe(fd); 

    close(0); 
    close(1); 
    int dret = dup2(fd[1], 1); 
    close(fd[1]); 

    while(1){ 

    char buf[256]; 
    system("whoami"); 
    int rret = read(fd[0], buf, 256); 

    if(/* something interesting */){ 
     return; 
    } 
    } 
} 

int main(int argc, char* argv[]){ 

    int children = 2; 

    for(unsigned work = 0; work < children; ++work){ 

    pid_t pid = fork(); 

    if(pid == 0){ 
     doWork(); 
     break; 
    } 
    } 
    int status; 
    wait(&status); 

    return 0; 
} 

这个例子有什么问题?我试图让每个子进程调用一个外部程序,然后从管道读取该程序的输出。我的代码只适用于儿童设置为1.平行叉管

编辑:我试图用fork/pipes来实现任务并行。父进程和子进程之间没有通信。每个子进程执行一个外部程序,读取输出,处理输出,并继续直到找到所需的输出。

+0

你和几个孩子有什么问题?你能解释一下这种行为吗? – 2011-02-04 15:13:33

+0

我收回之前说过的话。多个子进程运行良好。问题在于,对于多个子进程,程序花费很长时间才能完成,即使它应该更快,但只需一个子进程,只需几秒钟。我在SunOS 5.10上运行它;也许这跟它有关系? – Arlen 2011-02-04 15:44:34

回答

6

您需要在fork()之前创建管道,而不是之后。在你的代码中,只有子进程才会有管道。你需要两个进程来共享它。

例如:

int fd[2]; 
pid_t pid; 

if (pipe(fd)) { /* TODO: handle error */ } 

pid = fork(); 
if (pid < 0) { /* TODO: handle error */ } 

if (pid == 0) 
{ 
    /* We are the child. Set fd[1] as stdout. */ 
    if (dup2(fd[1], 1)) { /* TODO: handle error */ } 

    /* Close fd[0]; this process doesn't need it. */ 
    close(fd[0]); 

    do_work(); 
    exit(0); 
} 
else 
{ 
    /* We are the parent... */ 
    /* Close the other guy's write fd. */ 
    close(fd[1]); 

    /* Now read from fd[0] */ 
    /* Possibly waitpid() on child pid, etc. */ 
} 

另外:我喜欢在我fork()打电话fflush(stdout);。否则,您将使用printf()观察奇怪的行为。

1

你想产卵的孩子,然后将执行一些子进程,解析它的内容,解释它,然后退出?如果是这样,您需要为每个要创建的任务两次输入fork。第一次创建将处理子进程结果的子进程,第二次启动子进程。

类似的东西:

void ExecuteCommandAndInterpretResult(const char* command) 
{ 
    int fd[2]; 
    if (pipe(fd)) 
     exit(1); 

    pid_t pid = fork(); 
    if (pid < 0) 
     exit(1); 

    if (pid == 0) 
    { 
     if (dup2(fd[1], 1)) 
      exit(1); 

     close(fd[0]); 
     execl(command, basename(command), NULL); 
     exit(1); 
    } 
    else 
    { 
     int status; 

     close(fd[1]); 
     // do something with output from command 

     wait(&status); 
     exit(0); 
    } 
} 

#define CHILDREN 2 
int main() 
{ 
    unsigned int i; 
    pid_t pids[CHILDREN]; 

    for (i = 0; i < CHILDREN; i ++) 
    { 
     pids[i] = fork(); 
     if (pids[i] < 0) 
     { 
      // TODO: handle error 
     } 
     else if (pids[i] == 0) 
     { 
      ExecuteCommandAndInterpretResult("/usr/bin/ls"); 
      exit(0); 
     } 
    } 

    for (i = 0; i < CHILDREN; i ++) 
    { 
     if (pids[i] > 0) 
     { 
      int status; 
      waitpid(pids[0], &status, 0); 
     } 
    } 

    return 0; 
} 
0

你有没有考虑在孩子使用popen()执行whoami