在父进程恢复执行之前等待所有子进程 UNIX
Posted
技术标签:
【中文标题】在父进程恢复执行之前等待所有子进程 UNIX【英文标题】:Waiting for all child processes before parent resumes execution UNIX 【发布时间】:2010-12-03 09:55:10 【问题描述】:在我的程序中,我在有限的 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
【问题讨论】:
【参考方案1】:我认为您应该使用@987654321@
电话。它允许你等待“任何子进程”,所以如果你这样做了正确的次数,你应该是黄金。
如果失败(不确定保证),您可以在循环中执行蛮力方法,在您的每个子 PID 上使用 NOHANG
选项执行 waitpid()
,然后延迟一段时间在重做之前。
【讨论】:
请看代码,我做的和你说的一模一样。 @aditya:呃,不,我的建议是按照 jborque 的建议去做,我没有说任何关于使用信号处理程序的内容。【参考方案2】:与其在信号处理程序中调用waitpid
,不如在你按如下方式分叉所有进程之后创建一个循环:
while (pid = waitpid(-1, NULL, 0))
if (errno == ECHILD)
break;
程序应该在循环中挂起,直到没有更多的孩子。然后它会掉出来,程序将继续。作为额外的奖励,循环将在孩子们运行时阻塞waitpid
,因此您在等待时不需要繁忙的循环。
您也可以使用wait(NULL)
,它应该等同于waitpid(-1, NULL, 0)
。如果在 SIGCHLD 中你不需要做任何其他事情,你可以将其设置为 SIG_IGN。
【讨论】:
我需要给 WNOHANG 选项,因为如果有很多孩子几乎同时传递 SIGCHLD 信号,并且由于信号在 UNIX 中没有排队,如果我使用 0,那么我将能够只捕获一个信号,就会留下僵尸。 补充一点,-1 将检查任何子 pid(为了清楚起见,也可以使用 WAIT_ANY)。 @aditya:僵尸进程正等着你调用 wait()(或 wait_pid())。只要你这样做,它们就会消失,无论你是否捕捉到信号。所以 fork() 循环之后的 wait() 循环会清除所有的僵尸。 同意 -- 如果您使用的是wait/waitpid
,那么您不需要自己处理SIGCHLD
。以上是关于在父进程恢复执行之前等待所有子进程 UNIX的主要内容,如果未能解决你的问题,请参考以下文章