Przeszukuję różne źródła, ale nie mogę znaleźć dobrego opisu anatomii zbierania dzieci. To prosty przypadek tego, co chciałbym zrozumieć.
$ cat <( sleep 100 & wait ) &
[1] 14247
$ ps ax -O pgid | grep $$
12126 12126 S pts/17 00:00:00 bash
14248 12126 S pts/17 00:00:00 bash
14249 12126 S pts/17 00:00:00 sleep 100
14251 14250 S pts/17 00:00:00 grep --color=auto 12126
$ kill -2 14248
$ ps ax -O pgid | grep $$
12126 12126 S pts/17 00:00:00 bash
14248 12126 Z pts/17 00:00:00 [bash] <defunct>
14249 12126 S pts/17 00:00:00 sleep 100
14255 14254 S pts/17 00:00:00 grep --color=auto 12126
Dlaczego zombie czeka na dziecko?
Czy możesz to wyjaśnić? Czy muszę znać C i czytać kod źródłowy Bash, aby lepiej to zrozumieć, czy też jest jakaś dokumentacja? Już skonsultowałem:
- różne linki na tej stronie i Przepełnienie stosu
- Linia poleceń Linuksa autorstwa W. Shottsa
man bash
- Podręcznik referencyjny Bash (w dokumentach źródłowych Bash)
- Przewodnik Bash dla początkujących @ tldp.org
- Advanced Bash-Scripting Guide
GNU bash, wersja 4.3.42 (1) -release (x86_64-pc-linux-gnu)
Linux 4.4.0-31-generic # 50-Ubuntu SMP Środa 13 lipca 00:07:12 UTC 2016 x86_64 x86_64 x86_64 GNU / Linux
Odpowiedzi:
Zombie nie czeka na swoje dziecko. Jak każdy proces zombie, pozostaje tam, dopóki jego rodzic go nie odbierze.
Powinieneś wyświetlić wszystkie zaangażowane procesy, aby zrozumieć, co się dzieje, a także spojrzeć na PPID. Użyj tego wiersza poleceń:
Rodzicem procesu, który zabijasz, jest
cat
. Dzieje się tak, że bash uruchamia poleceniecat <( sleep 100 & wait )
w tle w podpowłoce. Ponieważ jedyne, co robi ta podpowłoka, to skonfigurowanie przekierowania, a następnie uruchomienie zewnętrznego polecenia, ta podpowłoka jest zastępowana przez zewnętrzne polecenie. Oto podsumowanie:fork
poleceniecat <( sleep 100 & wait )
w tle u dziecka (14247).pipe
aby utworzyć potok, a następniefork
dziecko, aby uruchomić podstawienie procesusleep 100 & wait
.fork
do bieganiasleep 100
w tle. Ponieważ wnuk nie jest interaktywny, proces w tle nie działa w osobnej grupie procesów. Wnuk czeka nasleep
wyjście.setpgid
(jest to zadanie w tle w interaktywnej powłoce, więc otrzymuje własną grupę procesów), a następnieexecve
uruchamia sięcat
. (Jestem trochę zaskoczony, że podstawienie procesu nie występuje w grupie procesów w tle).cat
, który nie wie nic o żadnym procesie potomnym i nie ma połączeń biznesowychwait
. Ponieważ rodzic wnuka nie zbiera go, wnuk pozostaje zombie.cat
wychodzi - albo dlatego, że go zabijesz, albo dlatego, żesleep
wraca i zamyka potok, więccat
widzi koniec swojego wejścia. W tym momencie rodzic zombie umiera, więc zombie jest zbierane przez init i init zbiera je.Jeśli zmienisz polecenie na
następnie
cat
uruchamia się w osobnym procesie, a nie w potomku oryginalnego procesu bash: pierwsze dziecko musi zostać w tyle, aby uruchomićecho done
. W takim przypadku, jeśli zabijesz wnuka, nie pozostanie on jako zombie, ponieważ dziecko (które w tym momencie nadal wykonuje bash) zbiera je.Zobacz także Jak Linux obsługuje proces zombie i czy zombie może mieć sieroty? Czy sierocym dzieciom przeszkadza zbieranie zombie?
źródło
cat
), który nie czeka na 14248 (czekającysleep
)? Czy jest jakaś pamięć o tym, kto na kogo czeka, którego dziecko (14247) straciło, a oryginalna bash (14246) nie, czy może lista sygnałów, takich jak SIGCHLD, o kim należy zadzwonić i 14247 (teraz uruchomionybash
) wypisać się z chodzi o 14248?wait
swoje dziecko, tzn. zbiera je. Widzę, jak byłoby to mylące, usunąłem to zdanie, które nie było nawet w odpowiednim momencie chronologicznie mówiąc. Informacja o tym, że proces umarł, trafia do jego rodzica, proces nie może „subskrybować”, aby otrzymywać informacje o śmierci innego procesu.Zombie nie czeka na dziecko. Zamiast zombie jest proces, który już umarł (przez własną rękę, albo został zabity - jak w przykładzie), miał swój kod, dane i stos zwalniane, a teraz zawiera tylko jego kod wyjścia, czekając na jego rodzic zadzwonić , aby je odzyskać (a zatem w końcu całkowicie wyczyść wpis procesu z tabeli procesów)
wait(2)
W twoim przykładzie, kiedy sen się skończy (lub zostanie zabity), rodzic przeczyta status wyjścia i zbierze zombie. Zobacz wyżej wymienione
wait(2)
szczegóły.źródło