2017-01-31 4 views
1

Warum endet das Programm nicht? Das Kind hängt nach dem Drucken, was es zu drucken hat. Wenn der Elternprozess statt des Kindes schlief, hätte es funktioniert, aber warum ist das so? Ich habe auch versucht, am Ende jedes Prozesses den Ausgang aufzurufen, aber mit dem gleichen Ergebnis. Muss ich immer auf das Ende des Kindes warten?Warum hängt diese Gabel?

int main(){ 

    int pid = fork(); 

    char s[100] = "Hello"; 

    if(pid > 0){ 
     printf("FIRST PRINT IN PARENT: %s\n", s); 
     strcat(s, " - PARENT"); 
     printf("SECOND PRINT IN PARENT: %s\n", s); 
    } 
    else if(pid == 0){ 
     printf("IMMEDIATELY IN CHILD: %s\n", s); 
     sleep(2); 
     printf("AFTER 2 SCONDS IN CHILD: %s\n", s); 
    } 
    return 0; 
} 
+1

Sind Sie sicher, dass * * it "hängt"? Es ist nicht so, dass das Terminal die Ausgabe des Kinds druckt und die Eingabeaufforderung einfach nicht erneut anzeigt? Drücken Sie die Eingabetaste und sehen Sie, was passiert. Wenn Sie in Ihrem Terminal genau hinsehen, werden Sie wahrscheinlich * die Eingabeaufforderung * vor der letzten Ausgabe des Kinds * sehen. –

+1

Nicht Sie, aber Ihre _shell_ wartet auf den _parent_ Prozess zu beenden. Sie müssten doppelt Gabel-um die Shell-Eingabeaufforderung sofort wiederherstellen – Ctx

+0

Der Code funktioniert für mich. Wenn Sie vermuten, dass es "hängt", ist es immer noch in der "ps" -Ausgabe sichtbar? – cdarke

Antwort

0

Die Shell gibt Ihnen die Eingabeaufforderung zurück, sobald der untergeordnete Prozess (d. H. Der übergeordnete Prozess in Ihrem Code) beendet wird. Jedoch es nicht über den untergeordneten Prozess wissen, dass Ihr Code gestartet wurde.

Die Quelle der Probleme, die Sie beobachtet haben, ist, dass Ihr Elternprozess nicht auf für sein Kind wartet. Verwenden Sie wait(2) Systemaufruf, z. B. wait(0);, im übergeordneten Prozess.

Das allgemeine Risiko, nicht auf untergeordnete Prozesse zu warten, besteht darin, dass Sie möglicherweise mit zombie processes enden; umgekehrt, orphan processes (wenn der Elternprozess zuerst beendet wird).

1

Wenn das übergeordnete Element beendet wird, kann es ein Signal (SIGHUP) an das untergeordnete Element senden. Wenn dies der Fall ist und das Kind dieses Signal nicht erkennt, stirbt das Kind.

In der Vergangenheit war der Standardwert, dass ein Prozess SIGHUP an seine untergeordneten Elemente sendet, wenn er beendet wird. Heutzutage senden viele Linux-Distributionen standardmäßig nicht SIGHUP.

Ich habe versucht, Ihren Code auf RHEL und der Kind-Prozess wurde nicht getötet. So stirbt der Elternteil und die Steuerung kehrt zur Shell zurück. Das Kind fährt fort und druckt seine zweite Ausgabe 2 Sekunden später.

Wenn das Kind eine SIGHUP empfängt, wird es nicht hängen. Es stirbt, und die letzte Zeichenfolge wird nie gedruckt.

In Linux können Sie einschalten SIGHUP über das prctl Systemaufruf:

#include <sys/prctl.h> 
prctl(PR_SET_PDEATHSIG, SIGHUP); 

Verwandte Frage: how-to-make-child-process-die-after-parent-exits