13

在我的程序中,我在有限的 while 循环中分叉(并行)子进程并在每个子进程上执行 exec。我希望父进程仅在所有子进程终止后才能恢复执行(此 while 循环之后的点)。我该怎么做?

我尝试了几种方法。在一种方法中,我在 while 循环之后让父级暂停,并仅在 waitpid 返回错误 ECHILD(没有子级剩余)时从 SIGCHLD 处理程序发送一些条件,但我在这种方法中面临的问题甚至在父级完成所有进程的分叉之前,retStat 变为-1

    void sigchld_handler(int signo) {
        pid_t pid;
        while((pid= waitpid(-1,NULL,WNOHANG)) > 0);
        if(errno == ECHILD) {
            retStat = -1;
        }
    }

    **//parent process code**
    retStat = 1;
    while(some condition) {
       do fork(and exec);
    }

    while(retStat > 0)
        pause();
//This is the point where I want execution to resumed only when all children have finished
4

2 回答 2

21

与其waitpid在信号处理程序中调用,不如在所有进程分叉后创建一个循环,如下所示:

while (pid = waitpid(-1, NULL, 0)) {
   if (errno == ECHILD) {
      break;
   }
}

程序应该挂在循环中,直到没有更多的孩子。然后它会掉出来,程序将继续。作为额外的奖励,循环将在waitpid孩子运行时阻塞,因此您在等待时不需要繁忙的循环。

您也可以使用wait(NULL)which 应该等同于waitpid(-1, NULL, 0). 如果在 SIGCHLD 中您不需要做任何其他事情,您可以将其设置为 SIG_IGN。

于 2009-10-02T17:49:20.680 回答
0

我认为你应该使用waitpid()电话。它允许你等待“任何子进程”,所以如果你这样做了正确的次数,你应该是黄金。

如果失败(不确定保证),您可以在循环中执行蛮力方法,对您的每个子 PID 执行一个waitpid()选项NOHANG,然后在再次执行之前延迟一段时间。

于 2009-10-02T17:46:48.897 回答