2015-02-21 9 views
27

Ich habe in Büchern und Online-Ressourcen gelesen, dass der Systemaufruf fork() eine Kopie des aktuellen Prozesses erstellt und beide Prozesse ab dem Punkt nach der Verzweigung ausgeführt werden() Systemaufruf wird gemacht. Ist es richtig?Das Verhalten des fork() - Systemaufrufs unter Linux in diesem Code

Wenn es richtig ist, warum druckt der Code "Test Test"? Es sollte "Test" nur einmal (durch den Elternprozess) drucken.

#include <sys/types.h> /* pid_t */ 
#include <sys/wait.h> /* waitpid */ 
#include <stdio.h>  /* printf, perror */ 
#include <stdlib.h> /* exit */ 
#include <unistd.h> /* _exit, fork */ 


int main(void) 
{ 
    int ctr =1; 
    int pc = 1; 
    printf("%s", "Test "); 
    pid_t pidmain = fork(); 
    return EXIT_SUCCESS; 
} 
+12

Fügen Sie der Zeichenfolge "test" ein "\ n" hinzu. – wildplasser

+0

@WildPlasser überraschend nach dem Hinzufügen \ n Ich habe Test (Single Time) nicht 2 mal. Aber warum? –

+16

Zeilenpufferung von stdout. Die fork() d-Kopien Ihres Programms haben beide einen halbgefüllten Puffer auf stdout, der beim Programm-Exit geleert wird. (beide Ausgänge). Um dies zu demonstrieren, können Sie auch einen Schlaf (1) kurz vor dem fork() hinzufügen – wildplasser

Antwort

37

Wenn Sie fork() das Betriebssystem aufrufen erstellt eine Kopie der aktuellen Prozess gesamten Speicher (es tatsächlich den Speicher nicht kopiert werden, da es die MMU kann dies effizient tun).

Da stdout standardmäßig gepuffert ist, wird die Nachricht nur gedruckt, sobald ein Zeilenumbruch geschrieben oder der Datenstrom gelöscht wird. Wenn Sie einen neuen Prozess forken, wird der aktuelle Schreibpuffer (der "Test" enthält) ebenfalls im neuen Prozess dupliziert. Dies wird dann gedruckt, sobald der Prozess beendet wird, da dies implizit die Standardausgabe schließt (und löscht). Wenn Sie die printf("%s", "Test "); durch printf("%s\n", "Test "); ersetzen oder einen Anruf fflush(stdout); vor der fork() hinzufügen, sehen Sie die erwartete Ausgabe.

+6

oder wenn die C-Bibliothek entscheidet, dass es zu viel im Puffer zu sein beginnt ... Es wäre falsch, sich auf die Ausgabe zu verlassen, die im Puffer verbleibt und während des Gabelungsaufrufs kopiert wird. –

18

An der Stelle, an der Sie fork aufrufen, haben beide Prozesse die Zeichenfolge "Test" in ihren Puffern für die Standardausgabe. Wenn jeder Prozess beendet wird, spülen beide diesen Text zum Ausgang (siehe Erläuterung exit). Sie könnten (wie vorgeschlagen) dem Puffer eine neue Zeile hinzufügen (und es würde aufgrund der Pufferung herauskommen - siehe setbuf zur Erklärung). Oder Sie könnten fflush (stdout) vor der Verzweigung aufrufen und genau das erhalten, wonach Sie gefragt haben - die Zeichenfolge "Test".

+0

Danke, dass Sie auf nützliche Links hingewiesen haben. –

Verwandte Themen