fork () et wait () avec deux processus enfants

Je dois utiliser les fonctions fork () et wait () pour terminer une affectation. Nous modélisons le comportement non déterministe et avons besoin du programme pour générer un fork () s’il y a plus d’une transition possible.

Afin d’essayer de comprendre comment le fork et l’attente fonctionnent, je viens de créer un programme simple. Je pense que je comprends maintenant comment les appels fonctionnent et que cela irait bien si le programme ne se ramifiait qu’une seule fois car le processus parent pouvait utiliser le statut de sortie du processus enfant unique pour déterminer si le processus enfant atteignait ou non l’état d’acceptation.

Comme vous pouvez le voir dans le code qui suit, je veux pouvoir gérer des situations où il doit y avoir plusieurs processus enfants. Mon problème est que vous ne semblez pouvoir définir le statut qu’en utilisant une fonction _exit une fois. Ainsi, comme dans mon exemple, le statut de sortie testé par le processus parent indique que le premier processus enfant a émis le statut 0, mais ne dispose pas d’informations sur le deuxième processus enfant.

J’ai simplement essayé de ne pas quitter () sur un rejet, mais alors ce processus enfant continuerait et, en réalité, il semblerait qu’il y ait deux processus parent.

Désolé pour la gaufre, mais je vous serais reconnaissant si quelqu’un pouvait me dire comment mon processus parent pourrait obtenir les informations d’état sur plusieurs processus enfants, ou je serais heureux que le processus parent remarque uniquement les statuts d’acceptation des processus enfants, mais dans ce cas, j’aurais besoin de sortir des processus enfants qui ont un statut de rejet.

Mon code de test est le suivant:

#include  #include  #include  #include  #include  int main(void) { pid_t child_pid, wpid, pid; int status = 0; int i; int a[3] = {1, 2, 1}; for(i = 1; i < 3; i++) { printf("i = %d\n", i); pid = getpid(); printf("pid after i = %d\n", pid); if((child_pid = fork()) == 0) { printf("In child process\n"); pid = getpid(); printf("pid in child process is %d\n", pid); /* Is a child process */ if(a[i]  0) { /* Is the parent process */ pid = getpid(); printf("parent_pid = %d\n", pid); wpid = wait(&status); if(wpid != -1) { printf("Child's exit status was %d\n", status); if(status > 0) { printf("Accept\n"); } else { printf("Complete parent process\n"); if(a[0] < 2) { printf("Accept\n"); } else { printf("Reject\n"); } } } } return 0; } 

Il me semble que le problème fondamental est que vous avez un appel wait() plutôt qu’une boucle qui attend jusqu’à ce qu’il n’y ait plus d’enfants. Vous n’attendez également que si le dernier fork() réussi plutôt que si au moins un fork() réussi.

Vous ne devez utiliser que _exit() si vous ne souhaitez pas effectuer d’opérations de nettoyage normales, telles que le vidage des stream de fichiers ouverts, y compris la stdout . Il y a des occasions d’utiliser _exit() ; Ce n’est pas l’un d’eux. (Dans cet exemple, bien sûr, les enfants peuvent simplement renvoyer au lieu d’appeler directement exit() car le retour de main() équivaut à quitter avec le statut renvoyé. ainsi de suite dans une fonction autre que main() , puis exit() est souvent approprié.)


Hacked, version simplifiée de votre code qui donne les diagnostics que je voudrais. Notez que votre boucle for ignoré le premier élément du tableau (le mien ne le fait pas).

 #include  #include  #include  #include  int main(void) { pid_t child_pid, wpid; int status = 0; int i; int a[3] = {1, 2, 1}; printf("parent_pid = %d\n", getpid()); for (i = 0; i < 3; i++) { printf("i = %d\n", i); if ((child_pid = fork()) == 0) { printf("In child process (pid = %d)\n", getpid()); if (a[i] < 2) { printf("Should be accept\n"); exit(1); } else { printf("Should be reject\n"); exit(0); } /*NOTREACHED*/ } } while ((wpid = wait(&status)) > 0) { printf("Exit status of %d was %d (%s)\n", (int)wpid, status, (status > 0) ? "accept" : "reject"); } return 0; } 

Exemple de sortie (MacOS X 10.6.3):

 parent_pid = 15820 i = 0 i = 1 In child process (pid = 15821) Should be accept i = 2 In child process (pid = 15822) Should be reject In child process (pid = 15823) Should be accept Exit status of 15823 was 256 (accept) Exit status of 15822 was 0 (reject) Exit status of 15821 was 256 (accept) 

Placez votre fonction wait () dans une boucle et attendez tous les processus fils. La fonction wait renverra -1 et errno sera égal à ECHILD si plus aucun processus enfant n’est disponible.

shiny exemple Jonathan Leffler, pour que votre code fonctionne sur SLES, je devais append un en-tête supplémentaire pour autoriser l’object pid_t 🙂

 #include