Wenn ich killall -9 name
ein Programm tötete, wurde der Staat zum Zombie. Einige Minuten später hörte es wirklich auf. Also, was passiert in diesen Minuten?
Das Programm empfängt tatsächlich nie das SIGKILL-Signal, da SIGKILL vollständig vom Betriebssystem / Kernel verarbeitet wird.
Wenn SIGKILL für einen bestimmten Prozess gesendet wird, beendet der Scheduler des Kernels sofort die Bereitstellung von mehr CPU-Zeit für die Ausführung von User-Space-Code für diesen Prozess. Wenn der Prozess Threads hat, die zum Zeitpunkt der Entscheidung des Schedulers User-Space-Code auf anderen CPUs / Cores ausführen, werden diese Threads ebenfalls gestoppt. (In Single-Core-Systemen war dies früher viel einfacher: Wenn der Scheduler als einziger CPU-Kern im System ausgeführt wurde, wurde der Prozess definitionsgemäß nicht gleichzeitig ausgeführt!)
Wenn der Prozess / Thread zum Zeitpunkt von SIGKILL Kernel-Code ausführt (z. B. einen Systemaufruf oder eine E / A-Operation, die mit einer Speicherzuordnungsdatei verknüpft ist), wird es etwas kniffliger: Nur einige Systemaufrufe sind unterbrechbar Der Kernel markiert den Prozess intern als in einem speziellen "sterbenden" Zustand, bis die Systemaufrufe oder E / A-Vorgänge aufgelöst sind. Die CPU-Zeit zur Behebung dieser Probleme wird wie gewohnt eingeplant. Unterbrechbare Systemaufrufe oder E / A-Vorgänge überprüfen, ob der Prozess, der sie aufgerufen hat, an einem geeigneten Haltepunkt abstirbt, und werden in diesem Fall vorzeitig beendet. Der unterbrechungsfreie Betrieb wird abgeschlossen und kurz vor der Rückkehr zum Benutzerbereichscode auf einen "sterbenden" Zustand überprüft.
Sobald alle In-Process-Kernel-Routinen aufgelöst sind, wird der Prozessstatus von "sterbend" in "tot" geändert und der Kernel beginnt mit der Bereinigung, ähnlich wie beim normalen Beenden eines Programms. Sobald die Bereinigung abgeschlossen ist, wird ein Ergebniscode größer als 128 zugewiesen (um anzuzeigen, dass der Prozess durch ein Signal beendet wurde; die unordentlichen Details finden Sie in dieser Antwort ), und der Prozess wechselt in den Status "Zombie" . Die Eltern des getöteten Prozesses werden mit einem SIGCHLD-Signal benachrichtigt.
Infolgedessen wird der Prozess selbst niemals die Möglichkeit erhalten, die Informationen, die er als SIGKILL erhalten hat, tatsächlich zu verarbeiten.
Wenn sich ein Prozess in einem "Zombie" -Zustand befindet, bedeutet dies, dass der Prozess bereits tot ist, der übergeordnete Prozess dies jedoch noch nicht bestätigt hat, indem er den Beendigungscode des toten Prozesses mithilfe des wait(2)
Systemaufrufs liest . Grundsätzlich ist die einzige Ressource, die ein Zombie-Prozess mehr verbraucht, ein Slot in der Prozesstabelle, der seine PID, den Beendigungscode und einige andere "wichtige Statistiken" des Prozesses zum Zeitpunkt seines Todes enthält.
Wenn der übergeordnete Prozess vor seinen untergeordneten Prozessen stirbt, werden die verwaisten untergeordneten Prozesse automatisch von der PID # 1 übernommen, die eine besondere Pflicht hat, weiterhin Anrufe zu tätigen, wait(2)
damit verwaiste Prozesse nicht als Zombies auftreten.
Wenn es einige Minuten dauert, bis ein Zombie-Prozess beendet ist, deutet dies darauf hin, dass der übergeordnete Prozess des Zombies Probleme hat oder seinen Job nicht ordnungsgemäß ausführt.
Es gibt eine flotte Beschreibung, was bei Zombie-Problemen in Unix-ähnlichen Betriebssystemen zu tun ist: "Sie können nichts für die Zombies selbst tun, da sie bereits tot sind. Töten Sie stattdessen den bösen Zombie-Meister! " (dh der Elternprozess der lästigen Zombies)
ps
: "S" steht für E / A-Wartezeiten, die der Kernel abbrechen kann, um ein Signal zu liefern, und "D" für diejenigen, die dies nicht können.