Rozważ następujący fragment kodu:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(void)
{
int i;
for(i = 0; i < 2; i++)
{
fork();
printf(".");
}
return 0;
}
Ten program generuje 8 kropek. Jak to możliwe? Czy zamiast tego nie powinno być 6 kropek?
Odpowiedzi:
fork()
Prymitywne często ciągnie wyobraźnię. Dopóki nie poczujesz tego, powinieneś prześledzić na papierze, czym jest każda operacja, i uwzględnić liczbę procesów. Nie zapominaj, że fork () tworzy niemal idealną kopię bieżącego procesu. Najbardziej znacząca różnica (dla większości celów) polega na tymfork()
, że zwracana wartość różni się między rodzicem a dzieckiem. (Ponieważ ten kod ignoruje zwracaną wartość, nie ma znaczenia).Tak więc na początku jest jeden proces. To tworzy drugi proces, z których oba drukują kropkę i pętlę. Podczas drugiej iteracji każdy tworzy kolejną kopię, więc cztery procesy drukują kropkę, a następnie kończą. Możemy więc z łatwością uwzględnić sześć kropek, tak jak się spodziewasz.
Jednak tak
printf()
naprawdę buforuje dane wyjściowe. Tak więc pierwsza kropka z okresu, w którym były tylko dwa procesy, nie pojawia się po napisaniu. Te kropki pozostają w buforze - który jest duplikowany w fork (). Buforowana kropka pojawia się dopiero po zakończeniu procesu. Cztery procesy drukują buforowaną kropkę, a nowy daje 8 kropek.Jeśli chcesz uniknąć takiego zachowania, zadzwoń
fflush(stdout);
poprintf()
.źródło
fork()
nie tworzy 2, a następnie kończy, tworzy tylko 1 dodatkowy proces.Masz niezatwierdzone bufory w strumieniach wyjściowych . stdout jest buforowany liniowo, a bufor jest replikowany wraz z resztą procesu. Po zakończeniu programu nieprzydzielony bufor jest zapisywany dwukrotnie (raz dla każdego procesu). Oba używają
i
nie pokazuj problemu.
W pierwszym przykładzie utworzysz cztery procesy, które mają dwie kropki w buforze strumienia wyjściowego. Po zakończeniu każdego strumienia opróżnia bufor, generując osiem kropek.
źródło
gdy i = 0
Proces_1: Buforowany tekst = 1 kropka
Process_2 (utworzony przez Process_1): buforowany tekst = 1 kropka
gdy i = 1
Process_3 (utworzony przez Process_1): Dziedziczy 1 buforowaną kropkę z Process_1 i drukuje 1 kropkę samodzielnie. W sumie Process_3 drukuje 2 kropki.
Process_4 (utworzony przez Process_2): Dziedziczy 1 buforowaną kropkę z Process_2 i drukuje 1 kropkę samodzielnie. W sumie Process_4 drukuje 2 kropki.
Proces_1: Drukuje 2 kropki (jedna buforowana kropka, gdy i = 0, a druga kropka, gdy i = 1)
Proces_2: Drukuje 2 kropki (jedna buforowana kropka, gdy i = 0, a druga kropka, gdy i = 1)
Końcowy wynik: 8 kropek. :)
źródło