How to make parent wait for all child processes to finish?
Solution 1
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
waits for a child process to terminate, and returns that child process's pid
. On error (eg when there are no child processes), -1
is returned. So, basically, the code keeps waiting for child processes to finish, until the wait
ing errors out, and then you know they are all finished.
Solution 2
POSIX defines a function: wait(NULL);
. It's the shorthand for waitpid(-1, NULL, 0);
, which will suspends the execution of the calling process until any one child process exits.
Here, 1st argument of waitpid
indicates wait for any child process to end.
In your case, have the parent call it from within your else
branch.
Solution 3
Use waitpid() like this:
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!.");
}
}
Solution 4
Just use:
while(wait(NULL) > 0);
This ensures that you wait for ALL the child processes and only when all have returned, you move to the next instruction.
Donatello
Updated on July 05, 2022Comments
-
Donatello almost 2 years
I'm hoping someone could shed some light on how to make the parent wait for ALL child processes to finish before continuing after the fork. I have cleanup code which I want to run but the child processes need to have returned before this can happen.
for (int id=0; id<n; id++) { if (fork()==0) { // Child exit(0); } else { // Parent ... } ... }
-
Donatello over 10 yearsThanks for ur replies. I added in wait(NULL) into the non child section, and the program just hangs and the child processes don't even execute ??
-
xxx7xxxx over 10 yearsOH, That's not error made by wait(). You should put up your complete code to let me debug it. You code is too simple, just a model.
-
JH95 about 9 yearsThat doesn't wait for all the children to finish just the one child childPid. If there were more processes this wouldn't work.
-
Jason Enochs about 9 yearsOf course if you create more than one thread from a single parent process, you will have to modify this example accordingly. Providing an example with several forks would have made my answer look confusing.
-
OutFall over 8 yearshow would you modify this code for parent to wait for ALL children to finish?
-
Max Moe over 8 years@JasonEnochs I don't think is trivial to modify the example for multiple forks. If your code is just "looped"
n
times (put thewaitpid
call in the forking loop), then I think we get a serial execution of the child processes and maybe that's not desired. The answer by @adrisons below looks good. -
Greg Dunn over 7 yearsThe manpage for
wait
says that it waits for one of the children to terminate. As @WhozCraig mentioned above you need towait
forn
times. -
trinity420 about 7 yearsHere a more detailed explanation of the wait call: man7.org/linux/man-pages/man2/waitpid.2.html
-
kotchwane almost 4 yearsI use
while(wait(NULL) > 0);
so that the process waits for all its children to terminate. -
Twonky almost 4 yearsI wonder if it is safe to assume "error during wait()" equals to "no more childs to wait for".
-
Not me over 3 years
man 2 wait
says:ECHIILD (for wait()) The calling process does not have any unwaited-for children.
I think you could#include <errno.h>
and use that in the while. -
AnthonyD973 over 2 years@kotchwane If you do this, then what happens if the process calling
wait()
receives a signal? According to the manpage forwait()
,If wait() or waitpid() returns due to the delivery of a signal to the calling process, -1 shall be returned and errno set to [EINTR].