Co robi program, gdy wysyła sygnał SIGKILL?

39

Kiedy killall -9 namezabijałem program, stan stał się zombie. Kilka minut później naprawdę przestało. Co się dzieje w tych minutach?

haikun on
źródło

Odpowiedzi:

66

Program faktycznie nigdy nie odbiera sygnału SIGKILL, ponieważ SIGKILL jest całkowicie obsługiwany przez system operacyjny / jądro.

Kiedy SIGKILL dla określonego procesu jest wysyłany, program planujący jądra natychmiast przestaje dawać temu procesowi więcej czasu procesora na uruchomienie kodu przestrzeni użytkownika. Jeśli proces ma wątki wykonujące kod przestrzeni użytkownika na innych procesorach / rdzeniach w momencie, gdy program planujący podejmie tę decyzję, wątki te również zostaną zatrzymane. (W systemach jednordzeniowych było to o wiele prostsze: jeśli jedynym rdzeniem procesora w systemie był program planujący, z definicji nie działałby on jednocześnie!)

Jeśli proces / wątek wykonuje kod jądra (np. Wywołanie systemowe lub operację I / O skojarzoną z plikiem odwzorowanym w pamięci) w czasie SIGKILL, robi się to nieco trudniejsze: tylko niektóre wywołania systemowe są przerywane, więc jądro wewnętrznie zaznacza proces jako będący w specjalnym stanie „umierania” do czasu rozwiązania wywołań systemowych lub operacji we / wy. Czas procesora na ich rozwiązanie zostanie zaplanowany jak zwykle. Przerywalne wywołania systemowe lub operacje we / wy sprawdzą, czy proces, który je wywołał, umiera w odpowiednich punktach zatrzymania, i w takim przypadku zakończą się wcześniej. Operacje nieprzerwane dobiegną końca i sprawdzą stan „umierania” tuż przed powrotem do kodu przestrzeni użytkownika.

Po rozwiązaniu procedur wewnętrznych jądra stan procesu zmienia się z „umierania” na „martwy”, a jądro zaczyna go oczyszczać, podobnie jak w przypadku normalnego zakończenia programu. Po zakończeniu czyszczenia zostanie przypisany kod wynikowy większy niż 128 (aby wskazać, że proces został zabity sygnałem; zobacz tę odpowiedź, aby uzyskać bałagan w szczegółach ), a proces przejdzie w stan „zombie” . Rodzic zabitego procesu zostanie powiadomiony sygnałem SIGCHLD.

W rezultacie sam proces nigdy nie będzie miał szansy na przetworzenie informacji o otrzymaniu SIGKILL.

Gdy proces znajduje się w stanie „zombie”, oznacza to, że proces jest już martwy, ale jego proces nadrzędny jeszcze tego nie potwierdził, odczytując kod zakończenia martwego procesu za pomocą wait(2)wywołania systemowego. Zasadniczo jedynym zasobem, który zużywa proces zombie, jest miejsce w tabeli procesów, w którym znajduje się jego PID, kod wyjścia i niektóre inne „istotne statystyki” procesu w chwili jego śmierci.

Jeśli proces nadrzędny umiera przed swoimi potomkami, osierocone procesy potomne są automatycznie adoptowane przez PID # 1, który ma szczególny obowiązek ciągłego wywoływania wait(2), aby żadne osierocone procesy nie pozostały jak zombie.

Jeśli wyczyszczenie procesu zombie zajmuje kilka minut, sugeruje to, że proces nadrzędny zombie ma trudności lub nie wykonuje prawidłowo swojej pracy.

Mówiący z przymrużeniem oka, co robić w przypadku problemów z zombie w systemach operacyjnych typu Unix: „Nie możesz nic zrobić dla samych zombie, ponieważ są one już martwe. Zamiast tego zabij złego mistrza zombie! ” (tj. proces macierzysty kłopotliwych zombie)

telcoM
źródło
5
Co się stanie, jeśli proces zostanie wywołany przez jądro (np. Wykonując operacje wejścia / wyjścia) podczas wysyłania SIGKILL?
gidds
9
@gidds Albo I / O zostanie anulowane w celu wykonania SIGKILL, lub SIGKILL będzie opóźniony do momentu zakończenia I / O. Jest to różnica między stanami uśpienia „S” i „D” w ps: „S” oznacza, że ​​I / O czeka na anulowanie jądra w celu dostarczenia sygnału, a „D” dla tych, których nie może.
Zwol
6
Nie jest do końca dokładne stwierdzenie, że harmonogram natychmiast przestaje podawać czas procesora procesora. Proces jądra obsługi sygnału jest nadal wykonywany przez ten proces, ale proces będzie wykonywał tylko kod jądra, więc masz rację, gdy mówisz, że program nigdy nie odbiera sygnału. Proces wykona kod jądra odpowiedzialny za większość czyszczenia zasobów (otwarte pliki, pamięć wirtualna itp.). Ostatnim krokiem tego kodu czyszczenia jest zmiana stanu procesu na zombie i wywołanie programu planującego. Wtedy to już nigdy nie zostanie zaplanowane.
kasperd
4
@gidds Proces może przebiegać w co najmniej czterech różnych stanach. W tej chwili może być uruchomiony kod jądra lub może spać w jednym z trzech różnych stanów uśpienia. Stany uśpienia mogą być przerywane, nieprzerywalne lub nieprzerywalne, z wyjątkiem śmiertelnych sygnałów. Jeśli jest w trybie nieprzerwanego snu, będzie spał tak długo, jak będzie to potrzebne, i tylko po przebudzeniu będzie miał szansę umrzeć. Jeśli był w jednym z dwóch pozostałych stanów uśpienia, zostanie natychmiast obudzony i zaplanowany, gdy tylko będzie dostępny procesor.
kasperd,
2
@gidds To, co stanie się dalej, zależy od kodu jądra, w którym był uruchomiony. Bez względu na to, czy był już uruchomiony, czy najpierw musiał zostać obudzony, a następnie mógł zacząć uruchamiać kod jądra, w którym był w tym czasie, będzie mógł kontynuować. I ten kod jądra jest odpowiedzialny za zauważenie, że procesowi nakazano umrzeć i odpowiednio postępować. W większości przypadków właściwym sposobem radzenia sobie z tym w kodzie jądra jest po prostu zwrócenie błędu z jakiejkolwiek funkcji, którą wykonywał. Po rozwinięciu stosu wywołań jądra kod obsługi sygnału może przejąć tuż przed powrotem do trybu użytkownika.
kasperd