Fork () gałęzie bardziej niż oczekiwano?

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 wyświetla 8 kropek. Jak to możliwe? Czy zamiast tego nie powinno być 6 kropek?

 188
Author: Jens, 2012-06-21

3 answers

Prymitywy często rozciągają 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 prawie idealną kopię bieżącego procesu. Najważniejszą różnicą (dla większości celów) jest to, że wartość zwracana fork() różni się między rodzicem a dzieckiem. (Ponieważ ten kod ignoruje zwracaną wartość, nie robi to żadnej różnicy.)

Więc na początku jest jeden proces. Tworzy to drugi proces, który drukuje kropkę i pętlę. Podczas drugiej iteracji każdy tworzy kolejną kopię, więc cztery procesy drukują kropkę, a następnie kończą. Więc możemy łatwo rozliczyć sześć kropek, jak się spodziewasz.

Jednak to, co naprawdę robi printf(), to buforowanie jego wyjścia. Tak więc pierwsza kropka z czasów, gdy były tylko dwa procesy, nie pojawia się po zapisaniu. Kropki te pozostają w buforze-który jest duplikowany w fork (). Dopiero po zakończeniu procesu że pojawia się buforowana kropka. Cztery procesy drukowania buforowanej kropki, plus nowy daje 8 kropek.

Jeśli chcesz uniknąć takiego zachowania, zadzwoń fflush(stdout); po printf().

 247
Author: wallyk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-21 06:58:19

Masz niezatwierdzone bufory w strumieniach wyjściowych . stdout jest buforowany liniowo, a bufor jest replikowany razem z resztą procesu. Po zakończeniu programu bufor jest zapisywany dwukrotnie (raz dla każdego procesu). Zarówno za pomocą

printf("a\n");

I

printf("a "); fflush(stdout);
Nie pokazuj problemu.

W pierwszym przykładzie tworzysz cztery procesy, które mają po dwie kropki w buforze strumienia wyjściowego. Gdy każdy strumień się kończy, spłukuje swój bufor, generuje osiem kropek.

 70
Author: thiton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-21 07:04:49

Kiedy ja=0

Proces_1: buforowany tekst= 1 kropka

Proces_2 (utworzony przez Proces_1): buforowany tekst= 1 kropka

Kiedy ja=1

Proces_3 (utworzony przez Proces_1): dziedziczy 1 buforowaną kropkę z Proces_1 i wypisuje 1 kropkę samodzielnie. W sumie Proces_3 wypisuje 2 kropki.

Proces_4 (utworzony przez Proces_2): dziedziczy 1 buforowaną kropkę z Proces_2 i wypisuje 1 kropkę samodzielnie. W sumie Proces_4 wypisuje 2 kropki.

Proces_1: drukuje 2 kropki (jeden buforowana kropka, gdy i=0 i kolejna kropka, gdy i=1)

Process_2: drukuje 2 kropki (jedna buforowana kropka, gdy i=0 i druga kropka, gdy i=1)

Wynik końcowy: 8 kropek. :)

 2
Author: Tauseef,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-24 20:12:18