2014-01-25 20 views
6

Ich habe ein Problem mit der Gabel, dass ich nicht unterversand.Verständnis der Gabel in C

#include <stdio.h> 
    #include <string.h> 

    main(){ 
     printf("test 1.\n"); 

     fork(); 

     printf("test 2.\n"); 
    } 

der Ausgang ist:

Test 1.
Test 2.
Test 1.
Test 2.

Sollte ich bekommen werden nicht ...:
test1
test2
test2

Ich verstehe das wirklich nicht, weil fork Kindprozess nach dem fork() erstellen sollte; und nicht die Test1 erneut drucken.

+5

Was passiert, wenn Sie 'fflush (stdout) hinzufügen;' 'vor fork();'? – immibis

+1

Sie vermissen die 'unistd.h'-Kopfzeile. – Mat

+0

@KarolyHorvath +1 die Ausgabe ist 'test1 \ ntest2 \ ntest2' – atupal

Antwort

5

Wenn Sie printf anrufen, wird kein Text sofort gedruckt. Stattdessen wartet es, bis Sie eine Menge Text gedruckt haben, oder Sie rufen fflush(stdout), oder das Programm beendet. (Edit: Es gibt auch andere Dinge, die gepufferten Text gedruckt werden)

Wenn der Prozess Gabeln, kopiert es den Puffer von nicht gedrucktem Text (die "Test 1. \ n" enthält). Beide Prozesse drucken dann beim Verlassen "Test 1. \ n".

Aufruf fflush(stdout) vor fork() behebt dies, indem Sie sicherstellen, dass "Test 1. \ n" tatsächlich vor den Prozessgabeln gedruckt wird.

1

versuchen Sie dies:

void exit_message (void) 
{ 
    // use write to have an unbuffered output 
    char m[100]; 
    sprintf (m, "%d exit\n", getpid()); 
    write (1, m, strlen(m)); 
} 

main(){ 
    atexit (exit_message); 

    printf("%d test 1\n",getpid()); 

    fork(); 

    printf("%d test 2\n",getpid()); 
    } 

Die Ausgabe wird wie folgt aussehen:

14866 exit // <- parent process flushes its output at exit 
14866 test 1 // <- parent process: 1st printf 
14866 test 2 // <- parent process: 2nd printf 
14867 exit // <- forked process flushes its output at exit 
14866 test 1 // <- forked process: unflushed parent process output buffer 
14867 test 2 // <- forked process: 2nd printf 

wir die einzige printf durch den gegabelten Prozess gemacht sehen die letzte ist, wie erwartet.

Die vorherige Zeile ist ein Ghost des Ausgabepuffers stdout, der vor dem Löschen mit fork() dupliziert wurde.

machen stdout ungepufferte

main(){ 
    atexit (exit_message); 
    setvbuf(stdout, NULL, _IONBF, 0); 
    printf("%d test 1\n",getpid()); 

    fork(); 

    printf("%d test 2\n",getpid()); 
} 

des Geistes entledigt

14866 test 1 // <- parent process: 1st printf 
14866 test 2 // <- parent process: 2nd printf 
14866 exit // <- parent process exits 
14867 test 2 // <- forked process: 2nd printf 
14867 exit // <- forked process exits 
+0

Der Aufruf von 'setvbuf()' im ersten Beispiel soll '_IOFBF' (" voll gepuffert ") aber' _IONBF' übergeben. – alk

+0

@alk AH ok, ich verstehe. Ich hatte vergessen, die Linie zu entfernen. Post aktualisiert, danke. –