Procesy - fork i exec

Cześć. Muszę się nauczyc o procesach i wątkach. Spędziłem niemalze cały dzień, ale dalej nie czuje tego i nie potrafie tego zrobić.

Mam taki program:

png
Wiem, że fork() odpowiada za rozwidlenie i lecimy drugi raz to samo od momentu wywołania tej funkcji. Jeżeli chodzi o funkcję exec, to odpala się to co jest w argumentach i program nie leci dalej, chyba ze jest funkcja wait().

W execlp nie rozumiem dlaczego jest 2x echo, czemu nie może być tylko raz?

Mógłby mi ktos krok po kroku rozpisać jak to działa i narysować drzewo procesów?

W Uniksach się przyjęło, że pierwszym argumentem dla wywoływanego programu jest ścieżka do niego. Jest to spowodowane tym, że istnieją dowiązania, więc program możesz wywołać z wielu lokalizacji i np. bash potrafi udawać sh, jeżeli wywołasz go tak /bin/sh .

Nie wiem, w jakim języku piszesz ten program, ale wygląda na to, że nie sprawdzasz, czy jesteś w procesie rodzica czy dziecka. Dwa razy wywołujesz fork tylko wtedy, jeżeli po pierwszym wywołaniu kończysz proces dziecka pierwszego poziomu (tylko wtedy ma to sens). Jest to wykorzystywane do tego, by zamknięcie rodzica nie zamykało dziecka.

To jest zadanie z kolokwium. A język to oczywiście C. Mam napisać co się wysetili na ekranie.

Wg. mnie - nie można udzielić jednoznacznej odpowiedzi. To nie jest DOS, by mógł jednocześnie działać tylko jeden proces - tutaj jeden proces przy pierwszym uruchomieniu może wyprzedzić drugi, a przy innym wyświetlać po nim. Ogólnie, to oba procesy mogą wypisywać coś na przemian.

Tak, ale chodzi mniej więcej. Np. nie rozumiem dlaczego, gdy jest if(fork()) fork; to tutaj już się tworzy proces, a później wchodzi dalej do ifa jeżeli sprwadził warunek.
Ja myślałem, że od razu sprawdza warunek i jeżeli jest prwadziwy to wchodzi do ifa, a tutaj się tworzy nowy proces.

Do końca nie rozumiem, co chciałeś przekazać, ale w assemblerze to może wyglądać mniej więcej tak:

call fork
test eax,eax
jz WNowymProcesie

Nie wiem czy wynik zwrócony przez funkcję w Linuksie pod x86 jest w eax - na Windowsie jest w eax, a ja programowałem w assemblerze pod Windows i kiedyś tworzyłem własny kernel.

W każdym razie, jak widzisz, to najpierw wywoływana jest funkcja.
Wg. dokumentacji, fork zwraca 0 w procesie potomnym, a pid nowego procesu w procesie rodzica. Fork kopiuje wszystkie dane systemowe z poprzedniego procesu do nowego i masz dwa identyczne procesy, tylko o różnym identyfikatorze. W rzeczywistości, jeżeli to możliwe, to oba procesy mają identyczny adres w pamięci, a dopiero, gdy jeden coś chce zapisać w pamięci, jądro kopiuje dane z obszarów danych rodzica.

Edycja: Zapomniałem wyjaśnić, co robi ten kod w assemblerze.

  1. Call - wywołuje procedurę - tutaj fork. Nie wiem czy w Linuksie wywołania funkcji systemowych odbywają się poprzez bramki procedury. Raczej jest to przerwaniem i takim, który ma numer 80h. Tutaj podałem to jedynie dla zobrazowania.
  2. Test - odejmuje dwie, zadane wartości i ustawia rejestr flag w zależności od wyniku. Test nie zapisuje nigdzie wyniku odejmowania.
  3. JZ - skocz, jeżeli w rejestrze flag jest ustawiona flag zero.