Search code examples
cforkmultiprocessingwait

How to wait for all the children to terminate before the parent moves on?


I'm doing some parallel programming (multiprocessing) and I need the parent to:

  1. Fork several children

  2. AFTER all the children have been created, simply WAIT for all of them to terminate

  3. After all the children are terminated, do some other work.

This is what I tried:

 int main(int argc, char **argv[])
{

  int j, i;
  pid_t children[3];
  int pid;

  // Fork the processes
  for(j = 0; j < 3; j++){
    if((children[j] = fork()) == 0){
      // Child process
      for(i = 0; i < 2; i++){
        printf("child %d printing: %d\n", j, i);
      }
    }else {
        // In parent now
        while (pid = waitpid(-1, NULL, 0)) {
            if (errno == ECHILD) {
                break;
            }
        }
        
        printf("all children terminated. in parent now\n");
    }
  }

  return 0;
}

Doesn't give the correct output. "all children terminated. in parent now" gets printed out several times, even before all the children are dead. Also, for each process, I should see only 2 outputs, but I see more.


Solution

  • Is this more what you are trying to achieve? I've just set a simple count for each child with a delay to increase the parallelisation visibility.

    #include <sys/wait.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <errno.h>
    
    int main(int argc, char **argv[])
    {
      int i, j, k;
      int pid;
    
      // Fork the processes
      for(j = 0; j < 3; j++)
      {
        if (fork() == 0)
        {
            printf("starting child %d\n", j);
            // Child process - do your child stuff
            for (i = 0; i < 5; ++i)
            {
              for (k = 0; k < 10000000; ++k);
              printf("child %d printing: %d\n", j, i);
            }
             printf("child %d ending\n", j);
            // then just quit
            exit(0);
        }
      }
    
      j = 1;
      while (wait(NULL) > 0)
      {
        printf("%d child completed\n", j++);
      }
    
      // In parent now
      printf("all children terminated. in parent now\n");
    
      return 0;
    }
    

    The output I get is

    starting child 0
    starting child 1
    child 0 printing: 0
    starting child 2
    child 1 printing: 0
    child 0 printing: 1
    child 2 printing: 0
    child 1 printing: 1
    child 0 printing: 2
    child 0 printing: 3
    child 2 printing: 1
    child 1 printing: 2
    child 1 printing: 3
    child 0 printing: 4
    child 0 ending
    child 2 printing: 2
    1 child completed
    child 1 printing: 4
    child 1 ending
    2 child completed
    child 2 printing: 3
    child 2 printing: 4
    child 2 ending
    3 child completed
    all children terminated. in parent now