Parent process waits for all child processes to finish before continuing

13,200

Solution 1

You just have to launch the processes in a loop and after that, in the original process, to loop on wait until there is no more living child. Like this:

for (int i = 0; i < NUMBER_OF_PROCESSES; i++) {
    pid = fork();   
    if (pid == 0) { // child
        sleep(5 - i);
        printf("Hello from Child %d\n",i + 1);
        num++;
        return 0;
    }
    else if (pid==-1) {
        printf("Error\n");
        break; // out on failure
    }
}
// try to wait for any children while there exists at least one
while ((pid=waitpid(-1,&status,0))!=-1) {
  printf("Process %d terminated\n",pid);
}

So children will live concurrently and the parent will wait their termination.

Solution 2

You can launch all your child (and retain their pid), and after, you will use waitpid (see option for waiting any child) in a loop until their is no child left.

That sound good for you ?

Edit :

#define NB_PROCESSES 5

int main(void)
{
    pid_t pidChild[NB_PROCESSES];
    pid_t stoppedChild;
    int   nbChild                = 0;

    printf("Launching all child.\n");
    for (int i = 0; i < NB_PROCESSES; ++i) {
        if ((pidChild[i] = fork()) == -1) {
            printf("Error while fork the %d child : errno = '%s'.\n", i, strerror(errno));
        } else {
            if (pidChild[i] == 0) {
                sleep(NB_PROCESSES - i);
                printf("Hello from Child %d\n",i);
                return (0);
            } else {
                ++nbChild;
            }
        }
    }

    printf("Waiting all child.\n");
    while (nbChild) {
        stoppedChild = waitpid(WAIT_ANY, NULL, 0);
        for (int i = 0; i < NB_PROCESSES; ++i) {
            if (stoppedChild == pidChild[i]) {
                printf("Child %d stopped.\n", i);
            }
        }
        --nbChild;
    }


    printf("Hello from the process, currentPid : %d\n", getpid());

    return (0);
}

You can retain their pid like that.

Share:
13,200
1ang
Author by

1ang

Updated on June 04, 2022

Comments

  • 1ang
    1ang almost 2 years

    I want my parent process waits for all child processes to finish before continuing, and I have one solution.

    int status;
    
    pid_t pid = 0;
    
    int num = 0;
    
    
    for (int i = 0; i < NUMBER_OF_PROCESSES; i++)
    {
        pid = fork();
    
        if (pid == 0)
        {
            //printf("Hello from Child\n");
            sleep(5 - i);
            printf("Hello from Child %d\n",i + 1);
            num++;
            return 0;
        }
        else if (pid)
        {
            waitpid(pid, &status, 0);
            continue;
        }
        else
        {
            printf("Error\n");
            exit(1);
        }
    
    
    }
    
    printf("Hello from the process, currentPid : %d, pid : %d\n", getpid(), pid);
    
    return 0;
    

    But it seems that I have to wait each child process before it finish, is there any way can make all child processes have to be able to run in parallel?

  • 1ang
    1ang about 8 years
    I tried to use waitpid(-1,&status,0); without the while loop, but it fails, I thought that can wait all child process. I don't know why.
  • Jean-Baptiste Yunès
    Jean-Baptiste Yunès about 8 years
    waitpid only waits for one child (undetermined one in advance if first arg equals to -1)... My code works well.
  • Luis Colorado
    Luis Colorado about 8 years
    Good solution @Jean-BaptisteYunès. Just wait up to wait(2) returning an error. As exiting not waited processes become zombies, no need to go further.