How to make parent wait for all child processes to finish?

205,401

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 waiting 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.

Share:
205,401
Donatello
Author by

Donatello

Updated on July 05, 2022

Comments

  • Donatello
    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
    Donatello over 10 years
    Thanks 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
    xxx7xxxx over 10 years
    OH, 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
    JH95 about 9 years
    That 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
    Jason Enochs about 9 years
    Of 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
    OutFall over 8 years
    how would you modify this code for parent to wait for ALL children to finish?
  • Max Moe
    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 the waitpid 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
    Greg Dunn over 7 years
    The manpage for wait says that it waits for one of the children to terminate. As @WhozCraig mentioned above you need to wait for n times.
  • trinity420
    trinity420 about 7 years
    Here a more detailed explanation of the wait call: man7.org/linux/man-pages/man2/waitpid.2.html
  • kotchwane
    kotchwane almost 4 years
    I use while(wait(NULL) > 0); so that the process waits for all its children to terminate.
  • Twonky
    Twonky almost 4 years
    I wonder if it is safe to assume "error during wait()" equals to "no more childs to wait for".
  • Not me
    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
    AnthonyD973 over 2 years
    @kotchwane If you do this, then what happens if the process calling wait() receives a signal? According to the manpage for wait(), 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].