web-dev-qa-db-fra.com

Comment faire en sorte que les parents attendent que tous les processus enfants soient terminés?

J'espère que quelqu'un pourra nous éclairer sur la façon de faire attendre les parents ALL les processus enfants se terminent avant de continuer après le fork. Je souhaite exécuter le code de nettoyage, mais les processus enfants doivent être renvoyés avant que cela puisse se produire.

for (int id=0; id<n; id++) {
  if (fork()==0) {
    // Child
    exit(0);      
  } else {
    // Parent
    ...
  }
  ...
}
39
Donatello
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 attend la fin d'un processus enfant et renvoie le pid de ce processus enfant . En cas d'erreur (par exemple, lorsqu'il n'y a pas de processus enfant), -1 est retourné. Donc, fondamentalement, le code continue d'attendre la fin des processus enfants, jusqu'à ce que les erreurs waiting soient terminées, et vous saurez alors qu'elles sont toutes terminées.

46
adrisons

POSIX définit une fonction: wait(NULL);. C'est le raccourci pour waitpid(-1, NULL, 0);, qui suspend l'exécution du processus appelant jusqu'à ce qu'un processus enfant se termine. Ici, le premier argument de waitpid indique l'attente de la fin d'un processus enfant.

Dans votre cas, demandez au parent de l'appeler depuis votre branche else.

26
longdeqidao

Utilisez waitpid () comme ceci:

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!.");    
    }
}
22
Jason Enochs