Wie lässt man Eltern warten, bis alle untergeordneten Prozesse abgeschlossen sind?

Lesezeit: 4 Minuten

Benutzeravatar von Donatello
Donatello

Ich hoffe, jemand könnte etwas Licht ins Dunkel bringen, wie man die Eltern dazu bringt, zu warten ALLE Untergeordnete Prozesse müssen beendet werden, bevor nach dem Fork fortgefahren wird. Ich habe Bereinigungscode, den ich ausführen möchte, aber die untergeordneten Prozesse müssen zurückgegeben werden, bevor dies geschehen kann.

for (int id=0; id<n; id++) {
  if (fork()==0) {
    // Child
    exit(0);      
  } else {
    // Parent
    ...
  }
  ...
}

  • Sie werden feststellen, dass die von all diesen Forks zurückgegebenen Pids bei Ihrer Aufgabe besonders hilfreich sind, wenn es Ihnen wichtig ist, welches Kind wann verlassen wurde. Andernfalls wait() zum n mal.

    – WhozCraig

    19. Oktober 2013 um 2:43 Uhr


Benutzeravatar von adrisons
Adrisons

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 wartet auf a untergeordneten Prozess zu beenden, und gibt die des untergeordneten Prozesses zurück pid. Bei einem Fehler (z. B. wenn es keine untergeordneten Prozesse gibt), -1 ist zurück gekommen. Im Grunde wartet der Code also weiter darauf, dass untergeordnete Prozesse beendet werden, bis die waitFehler aus, und dann wissen Sie, dass sie alle fertig sind.

  • Ich frage mich, ob es sicher ist anzunehmen, dass “Fehler während des Wartens ()” gleich “keine weiteren Kinder zum Warten” sind.

    – Twonki

    20. Juni 2020 um 20:48 Uhr

  • man 2 wait sagt: ECHIILD (for wait()) The calling process does not have any unwaited-for children. Ich denke, du könntest #include <errno.h> und benutze das in der Zwischenzeit.

    – Nicht ich

    25. Oktober 2020 um 20:53 Uhr


Benutzeravatar von xxx7xxxx
xxx7xxxx

POSIX definiert eine Funktion: wait(NULL);. Es ist die Abkürzung für waitpid(-1, NULL, 0);, wodurch die Ausführung des aufrufenden Prozesses ausgesetzt wird, bis ein untergeordneter Prozess beendet wird. Hier, 1. Argument von waitpid gibt an, auf das Ende eines untergeordneten Prozesses zu warten.

Lassen Sie es in Ihrem Fall von den Eltern aus Ihrem Inneren heraus anrufen else Zweig.

  • Danke für eure Antworten. Ich habe in wait(NULL) in den nicht untergeordneten Abschnitt eingefügt, und das Programm hängt einfach und die untergeordneten Prozesse werden nicht einmal ausgeführt ??

    – Donatello

    19. Oktober 2013 um 3:10 Uhr

  • OH, das ist kein Fehler von wait(). Sie sollten Ihren vollständigen Code aufstellen, damit ich ihn debuggen kann. Ihr Code ist zu einfach, nur ein Modell.

    – xxx7xxxx

    19. Oktober 2013 um 3:41 Uhr

  • Die Manpage für wait sagt, dass es wartet eines der Kinder zu kündigen. Wie @WhozCraig oben erwähnt, müssen Sie wait zum n mal.

    – Greg Dunn

    19. Oktober 2016 um 17:55 Uhr

  • Hier eine genauere Erklärung der Warten Anruf: man7.org/linux/man-pages/man2/waitpid.2.html

    – Trinity420

    1. April 2017 um 11:36 Uhr

  • ich benutze while(wait(NULL) > 0); damit der Prozess wartet alle seine Kinder zu beenden.

    – Kotchwane

    20. Mai 2020 um 8:50 Uhr


Benutzeravatar von Jason Enochs
Jason Enochs

Verwenden Sie waitpid() wie folgt:

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

  • Das wartet nicht darauf, dass alle Kinder nur das eine Kind childPid beenden. Wenn es mehr Prozesse gäbe, würde dies nicht funktionieren.

    – JH95

    9. April 2015 um 17:49 Uhr

  • Wenn Sie mehr als einen Thread aus einem einzelnen übergeordneten Prozess erstellen, müssen Sie dieses Beispiel natürlich entsprechend ändern. Ein Beispiel mit mehreren Gabeln bereitzustellen, hätte meine Antwort verwirrend aussehen lassen.

    – Jason Henochs

    15. April 2015 um 16:25 Uhr

  • Wie würden Sie diesen Code ändern, damit Eltern warten, bis ALLE Kinder fertig sind?

    – OutFall

    13. Oktober 2015 um 23:06 Uhr


  • @JasonEnochs Ich denke nicht, dass es trivial ist, das Beispiel für mehrere Gabeln zu ändern. Wenn Ihr Code nur “geloopt” ist n mal (setzen Sie die waitpid Aufruf in der Forking-Schleife), dann denke ich, dass wir eine serielle Ausführung der untergeordneten Prozesse erhalten, und das ist vielleicht nicht erwünscht. Die Antwort von @adrisons unten sieht gut aus.

    – rocarvaj

    30. Dezember 2015 um 17:14 Uhr

Benutz einfach:

while(wait(NULL) > 0);

Dadurch wird sichergestellt, dass Sie auf ALLE untergeordneten Prozesse warten und erst dann zur nächsten Anweisung übergehen, wenn alle zurückgekehrt sind.

1419080cookie-checkWie lässt man Eltern warten, bis alle untergeordneten Prozesse abgeschlossen sind?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy