我希望有人能够解释一下如何让父进程在fork之后等待所有子进程完成后再继续。我有清理代码需要运行,但必须在子进程返回后才能执行。
for (int id=0; id<n; id++) {
if (fork()==0) {
// Child
exit(0);
} else {
// Parent
...
}
...
}
我希望有人能够解释一下如何让父进程在fork之后等待所有子进程完成后再继续。我有清理代码需要运行,但必须在子进程返回后才能执行。
for (int id=0; id<n; id++) {
if (fork()==0) {
// Child
exit(0);
} else {
// Parent
...
}
...
}
pid_t child_pid, wpid;
int status = 0;
//Father code (before child processes start)
for (int id=0; id<n; id++) {
if ((child_pid = fork()) == 0) {
//child code
exit(0);
}
}
while ((wpid = wait(&status)) > 0); // this way, the father waits for all the child processes
//Father code (After all child processes end)
wait
等待一个子进程终止,并返回该子进程的 pid
。如果出现错误(例如没有子进程),则返回 -1
。因此,基本上代码会一直等待子进程完成,直到 wait
出错,然后你就知道它们全部都已经完成了。
man 2 wait
说:ECHIILD (for wait()) The calling process does not have any unwaited-for children.
我认为你可以 #include <errno.h>
并在 while 循环中使用它。 - Not mePOSIX定义了一个函数:wait(NULL);
。它是waitpid(-1, NULL, 0);
的简写形式,该函数会挂起调用进程的执行,直到任何一个子进程退出。
在您的情况下,父进程应在else
分支中调用它。
wait
的 man 手册说它等待一个子进程终止。如@WhozCraig在上面提到的,你需要 wait
n
次。 - Greg Dunnwhile(wait(NULL) > 0);
。 - kotchwanewait()
的进程接收到信号会发生什么?根据wait()
的手册,如果wait()
或waitpid()
由于向调用进程传递信号而返回,则应返回-1并将errno设置为[EINTR]。 - adentinger像这样使用waitpid():
pid_t childPid; // the child process that the execution will soon run inside of.
childPid = fork();
if(childPid == 0) // fork succeeded
{
// Do something
exit(0);
}
else if(childPid < 0) // fork failed
{
// log the error
}
else // Main (parent) process after fork succeeds
{
int returnStatus;
waitpid(childPid, &returnStatus, 0); // Parent process waits here for child to terminate.
if (returnStatus == 0) // Verify child process terminated without error.
{
printf("The child process terminated normally.");
}
if (returnStatus == 1)
{
printf("The child process terminated with an error!.");
}
}
waitpid
调用放在forking循环中),那么我认为我们会得到子进程的串行执行,也许这并不是期望的结果。下面@adrisons的答案看起来不错。 - rocarvaj只需要使用:
while(wait(NULL) > 0);
wait()
函数等待执行n
次即可。 - WhozCraig