Wizualnie, co dzieje się widelec () w pętli
Próbowałem zrozumieć zachowanie
fork (). Tym razem w
for-loop. Przestrzegaj następującego kodu:
#include <stdio.h>void main()Oto wynik
{
int i; for (i=0;i<3;i++)
{
fork();// This printf statement is for debugging purposes
// getppid(): gets the parent process-id
// getpid(): get child process-id printf("[%d] [%d] i=%d\n", getppid(), getpid(), i);
} printf("[%d] [%d] hi\n", getppid(), getpid());
}
:
[6909][6936] i=0
[6909][6936] i=1
[6936][6938] i=1
[6909][6936] i=2
[6909][6936] hi
[6936][6938] i=2
[6936][6938] hi
[6938][6940] i=2
[6938][6940] hi
[1][6937] i=0
[1][6939] i=2
[1][6939] hi
[1][6937] i=1
[6937][6941] i=1
[1][6937] i=2
[1][6937] hi
[6937][6941] i=2
[6937][6941] hi
[6937][6942] i=2
[6937][6942] hi
[1][6943] i=2
[1][6943] hi
Jestem osobą bardzo wizualną i dlatego jedynym sposobem, aby naprawdę zrozumieć rzeczy, jest zrobienie diagramu. Mój instruktor powiedział, że to będzie 8
Witamy
sprawozdania. Napisałem i uruchomiłem kod i rzeczywiście było 8 instrukcji
hi
... Ale naprawdę tego nie rozumiałem. Więc narysowałem następujący diagram:
Wykres zaktualizowany o komentarze :)
Obserwacje:
>
- Proces macierzysty (główny) musi powtórzyć cykl 3 razy. Następnie wywoływana jest funkcja printf
- W każdej iteracji rodzica pętli for wywoływana jest funkcja fork ()
- Po każdym wywołaniu fork (), i jest inkrementowane, więc każde dziecko rozpoczyna pętlę for w punkcie i, zanim zostanie zwiększone
- Na końcu każdej pętli for wypisywane jest „hi”
Oto moje pytania:
>
- Czy mój schemat jest prawidłowy
- Dlaczego dane wyjściowe obejmują dwa wystąpienie
i = 0
- Jaka wartość
i
jest przenoszona na każde dziecko po fork () Jeśli ta sama wartośći
zostanie przeniesiona, kiedy „rozwidlanie” się zatrzyma - Czy zawsze jest tak, że
2 ^ n - 1
byłby sposobem zliczenia liczby podzielonych dzieci Więc tutajn = 3
, co oznacza2 ^ 3 - 1 = 8 - 1 = 7
dzieci, które jest poprawne
Nie znaleziono powiązanych wyników
Zaproszony:
Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się
3 odpowiedzi
Anonimowy użytkownik
Potwierdzenie od:
Zatem drukowane jest dwukrotnie, drukowane cztery razy, drukowane 8 razy i drukowane . 8 czasy.
Anonimowy użytkownik
Potwierdzenie od:
Małe wyjaśnienie do drugiego:
wygląda jak:
Zatem w procesach rozwidlonych (zarówno nadrzędnych, jak i podrzędnych) jest wartością przed przyrostem. Jednak przyrost jest wykonywany zaraz po , więc moim zdaniem diagram można uznać za poprawny.
Anonimowy użytkownik
Potwierdzenie od:
Czy mój schemat jest prawidłowy?
Tak, zasadniczo. To także bardzo dobry schemat.
Oznacza to, że poprawne jest interpretowanie etykiet i tak dalej jako odnoszących się do iteracji pełnej pętli. Jednak diagram
nie
pokazuje, że po każdej część bieżącej iteracji pętli po wywołaniu jest również wykonywana przez proces rozwidlony podrzędny.
Dlaczego w wyniku występują dwa wystąpienia ?
Ponieważ masz po , więc jest ono wykonywane zarówno przez proces nadrzędny, jak i właśnie rozwidlony proces potomny. Jeśli przesuniesz przed , zostanie on wykonany tylko przez rodzica (ponieważ proces potomny jeszcze nie istnieje).
Jaka wartość jest przenoszona na każde dziecko po ? Jeśli ta sama wartość zostanie przeniesiona, kiedy „rozwidlanie” się zatrzyma?
Wartość nie zmienia się na , więc dziecko widzi tę samą wartość co jego Parent.
W przypadku należy pamiętać, że jest wywoływana raz, ale zwracana dwukrotnie - raz w procesie nadrzędnym i raz w nowo sklonowanym procesie potomnym.
Aby uzyskać prostszy przykład, rozważ następujący kod:
Proces potomny utworzony przez jest (prawie) dokładnym klonem swojego rodzica i dlatego z własnego punktu widzenia "pamięta" jest jego rodzicem, dziedzicząc cały stan rodzica proces (w tym wszystkie wartości zmiennych, stos wywołań i instrukcje wykonywalne). Jedyną bezpośrednią różnicą (inną niż metadane systemowe, takie jak identyfikator procesu zwracany przez ) jest wartość zwracana przez , która w elemencie podrzędnym będzie wynosić zero proces, ale niezerowy (w rzeczywistości identyfikator procesu potomnego) w obiekcie nadrzędnym.
Czy zawsze jest tak, że byłby sposobem zliczenia liczby podzielonych dzieci? Więc tutaj , co oznacza dzieci, które jest poprawne?
Każdy proces, który staje się dwoma procesami (z wyjątkiem nietypowych błędów, w których może się nie powieść). Jeśli rodzic i dziecko nadal wykonują ten sam kod (to znaczy nie sprawdzają wartości zwracanej funkcji ani własnego identyfikatora procesu i rozgałęziają się do różnych ścieżek kodu na jego podstawie), to każde następne rozwidlenie podwaja liczbę procesów. Zatem tak, po trzech widełkach otrzymujesz łącznie 2³ = 8 procesów.