2012-05-22 18 views
6

Eksperymentowałem z fork() i zmieniłem kierunek, aby sprawdzić, czy instrukcje dotyczące powrotu u rodzica odnoszą się również do dziecka. Napisałem następujący prosty programDeklaracja przed dwukrotnym wydrukowaniem fork()

#include<stdio.h> 
#include<unistd.h> 
#include<stdlib.h> 

int main() 
{ 
    freopen("error.txt", "w+t", stdout); // From now on, stdout = error.txt 
    printf (" ERROR! WHY DONT U UNDERSTAND?\n"); 
    if (fork() == 0) 
    { 
     printf(" I AM CHILD\n"); 
     exit(0); 
    } 
    else- 
    { 
     printf (" EITHER I AM A PARENT OR SOMETHING GOT SCREWED\n"); 
    } 


    return 0; 
} 

Wyjście (error.txt) mam to

ERROR! WHY DONT U UNDERSTAND? 
EITHER I AM A PARENT OR SOMETHING GOT SCREWED 
ERROR! WHY DONT U UNDERSTAND? 
I AM CHILD 

Niespodziewanie, ERROR! WHY DONT U UNDERSTAND? jest drukowanie dwukrotnie choć wydaje się znacznie przed fork() nazywa i powinien drukuje tylko jeden raz rodzic.

Czy ktoś może rzucić trochę światła na to?

+0

Nie jestem tego pewien, ale upewnij się, że opróżnisz bufory io, przed widelcem. może bufory zostaną skopiowane do dziecka. – lupz

+2

Zapewniłoby to doskonałe pytanie dotyczące wywiadu! – dasblinkenlight

Odpowiedz

10

Ponieważ po reopen strumień nie jest interaktywny, jest w pełni zbuforowany i nie spłukuje się na '\n'. Przed wywołaniem fork bufor nadal zawiera komunikat, a po fork ten buforowany komunikat został zduplikowany (ponieważ oba procesy otrzymały własne kopie stdout), a następnie przepłukane przez rodzica i dziecko. Zobacz część 7.19.3 normy C.

Można tego uniknąć, dzwoniąc pod numer fflush tuż przed numerem fork.

+0

Nie wiem, że '\ n' nie działa jako automatyczne urządzenie przepłukujące po przekierowaniu. Dzięki i +1 –

+0

Możesz również użyć 'setvbuf' do rekonfiguracji' stdout'. –

3

Dzieje się tak z powodu buforowania. Zrób fflush zaraz po printf.

Oba procesy kończą się tą samą kopią wewnętrznych rzeczy, które są stdio i obie kontynuują, aby je opróżnić pod adresem exit. Możesz również zapobiec temu, jeśli zadzwonisz pod numer _exit w dziecku.

+0

Jeśli zmienię 'exit()' na '_exit()', dziecko nie drukuje niczego. np. 'I AM CHILD' brakuje w danych wyjściowych. Jaka jest różnica między 'exit()' a '_exit()'? –

+1

@Stacker '_exit' nie opróżnia buforów stdio. – cnicutar

1

Płukanie bufora rozwiąże problem. użyj fflush tuż po instrukcji print.

0

Wygląda na to, że ERROR! WHY DONT U UNDERSTAND jest nadal buforowany po rozwidleniu i zapisywany przez oba procesy.

Jeśli dodać

fflush(stdout); 

tuż po pierwszym printf() bufor wewnętrzny jest zaczerwieniona i to pojawia się tylko raz w pliku.