Wer führt zuerst nach fork() aus: parent oder the child?

Lesezeit: 4 Minuten

Ich weiß, dass es beides sein kann. Aber ich sehe immer, dass das Kind zuerst auf meinem UNIX-Terminal ausgeführt wird. Warum werden Eltern und Kind nicht parallel ausgeführt? Sie scheinen seriell ausgeführt zu werden. Liegt das daran, dass sie sich dasselbe Terminal teilen?

  • mögliches Duplikat von Kann die Ausführungsreihenfolge von fork() bestimmt werden?

    – Lekenstein

    29. Dezember 2011 um 21:35 Uhr

  • Kind unter Linux, nicht spezifiziert auf einer allgemeinen POSIX-Plattform.

    – PSkočik

    25. März 2019 um 15:08 Uhr

Benutzer-Avatar
NPE

Im Allgemeinen kann nichts über die relative Reihenfolge ihrer Ausführung gesagt werden.

Betrachten wir nun Ihr spezifisches Problem. Wenn:

  1. beide Prozesse benötigen eine nicht triviale Zeit, um ausgeführt zu werden, und
  2. Sie sagen, dass einer fertig läuft, bevor der andere fertig ist irgendein Fortschritt und
  3. es gibt ungenutzte CPU-Zyklen, und
  4. Dies geschieht jedes Mal, wenn Sie die Anwendung ausführen.

Höchstwahrscheinlich weist dies darauf hin, dass zwischen den beiden Prozessen eine (möglicherweise unbeabsichtigte) Synchronisierung stattfindet.

  • +1. Es obliegt dem zugrunde liegenden Scheduler, zu entscheiden, wie die verschiedenen Threads geplant werden.

    – Vicky

    13. Dezember 2011 um 19:13 Uhr

  • @aix: Beide machen Fortschritte. Ich mache ein einfaches printf in Elternteil und Kind. Ich sehe ihre printfs nie verschachtelt. Es ist immer ein untergeordnetes printf (~ 100 zusammengebündelt) … übergeordnetes printfs (zusammengebündelt) … untergeordnetes printfs …

    – Bruce

    13. Dezember 2011 um 19:33 Uhr

  • @Bruce: Sind Sie sicher, dass dies nicht auf die Ausgabepufferung zurückzuführen ist (schreiben Sie an das Terminal oder an eine Datei/Pipe)? Ebenfalls, top sollte Ihnen eine Vorstellung davon geben, ob die beiden Prozesse “parallel” laufen.

    – NPE

    13. Dezember 2011 um 19:41 Uhr


Eigentlich ist das das beabsichtigte Verhalten, auch wenn es derzeit nicht so funktioniert, wie es sollte, was bedeutet, dass der Elternteil vor dem Kind laufen kann und das Kind vor dem Elternteil laufen kann.

Das Ziel ist es, zuerst den untergeordneten Prozess auszuführen.

Kurz gesagt, die Logik dahinter ist, dass, wenn das Kind zuerst ausgeführt wird, der Overhead von Copy on Write (COW) eliminiert wird, wenn das Kind aufruft exec da der Elternteil keine Möglichkeit hat, in den Adressraum zu schreiben.

Wenn Sie vfork aufrufen, definieren fast alle Implementierungen, dass das untergeordnete Element zuerst ausgeführt wird und dann das übergeordnete Element. (Bis das untergeordnete Element exec aufruft). Sie werden also im Falle von vfork unabhängig vom Zeitplan eine serielle Ausführung bemerken Es werden zwei neue Prozesse erstellt. Sie können unabhängig voneinander ausgeführt werden (genau wie jeder andere Prozess). Welcher Prozess zuerst ausgeführt wird, hängt stark vom Scheduling-Algorithmus ab. Neben dem Planungsalgorithmus bestimmt die Anzahl der zu diesem Zeitpunkt laufenden Prozesse auch die Art der Ausgabe. Wenn Sie außerdem Standardbibliotheks-E / A-Funktionen verwenden, geben sie Daten in Bursts aus (wahrscheinlich nicht das richtige Wort). Das bestimmt auch ein Stück weit, wer zuerst schreiben darf. Hier ist ein Beispielcode (Das macht praktisch keinen Sinn, ist aber immer noch ein gutes Beispiel dafür Elternteil und Kind laufen tatsächlich synchron

  #include<stdio.h>
  #include<string.h>
  static void charAtTime(char buff[])
{
char *p=buff;
while(*p) {
putc(*p,stdout);
(p++);
}

}
    int main()
{
setbuf(stdout,NULL);   //set output stream to be unbuffered.Now each process will try to throw chars as soon as they are ready
int pid;
char buff[1000];
if((pid=fork())<0)   //First fork
    {
    fprintf(stderr,"Fork error\n");
    }
else if(pid==0)
    {
    strcpy(buff,"i am the child.I love beyblade.I love anime.I love pokemon\n");
   charAtTime(buff);    
  }
   else {
     int pid2=fork();   //secnd fork
     if(pid2==0){
     strcpy(buff,"I am the younger child\n");
         charAtTime(buff);
        }
   else {
int pid3;
pid3=fork();    //third fork
if(pid3==0)
    {
    strcpy(buff,"I am from the 2nd generation\n");
    charAtTime(buff);
    }
     else {
    strcpy(buff,"Our family tree is bit confusing\n");
    charAtTime(buff);
    }
        }

     strcpy(buff,"I am the big daddy of them.I have the right before them\n");
    }

   return 0;
    }

Bei meinem System kommt folgende Ausgabe

   i am thOeI u ra cmfha mtihley  yoIturne geea rmi  cshf irblodimt
   thceo i2nnlfdd .uIg elnseoivrnea gb
   teiyobnl
   ade.I love anime.I love pokemon   

Wenn Sie jedoch die Anzahl der Gabeln auf zwei reduzieren (nur zwei konkurrierende Prozesse), ist die Ausgabe weniger hässlich. Es ist das übergeordnete Element, das zuerst ausgeführt wird. (Wahrscheinlich, weil sein aktuell laufender Prozess ausgeführt wird, wenn der andere Prozess erstellt wird).

Es gibt nicht wirklich einen, der vor dem anderen ausgeführt wird. Es ist einfach so, dass die Eltern es tun werden fork() dann wait() damit das Kind fertig wird. Es kann sich sogar mehrmals verzweigen, wenn Sie beispielsweise eine Reihe von Befehlen verwenden.

Wie die anderen antworten, wissen Sie es vielleicht nicht, und Sie sollten sich nicht darauf verlassen.

Aber historisch gesehen werden unter Linux die Eltern weiterhin ausgeführt und danach die Kinder. Auf einem alten Linux-Kernel wurde es umgekehrt implementiert: schnelles Ausführen der Kinder, die wahrscheinlich an rufen werden exec. Auf diese Weise gibt es keine Kopie im Schreibspeicher (was bei jedem Schreibvorgang des Elternteils erfolgen sollte). Erraten Sie, was? Diese Änderungen haben viele Tools auf subtile Weise zerstört (und sind schwer zu debuggen), sodass sie rückgängig gemacht wurden. Ein Verlust der Optimierung!.

Legen Sie also nicht fest, welcher Prozess zuerst ausgeführt wird.

1370970cookie-checkWer führt zuerst nach fork() aus: parent oder the child?

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

Privacy policy