Der Beendigungsprozess
Sobald ein Prozess erstellt wurde, wie endet er? Die Beendigung eines Prozesses ist ein kritischer Teil des Prozesslebenszyklus und stellt sicher, dass Systemressourcen effektiv verwaltet werden.
A process beendet typischerweise durch den Aufruf des Systemaufrufs _exit. Diese Aktion signalisiert dem Kernel, dass der Prozess beendet ist und seine Ressourcen, wie Speicher und Dateideskriptoren, zurückgewonnen werden können. Beim Beenden übergibt der Prozess einen Beendigungsstatus an den Kernel, der ein ganzzahliger Wert ist. Konventionsgemäß signalisiert ein Status von 0 eine erfolgreiche Ausführung, während ein Wert ungleich Null auf einen Fehler hinweist.
Hinweis: Der Aufruf von _exit löscht den Prozess nicht sofort. Der übergeordnete Prozess muss die Beendigung seines Kindprozesses durch den Aufruf des Systemaufrufs wait bestätigen. Dieser Aufruf ermöglicht es dem Elternprozess, den Beendigungsstatus des Kindes abzurufen. Dieser zweistufige Mechanismus ist für die ordnungsgemäße Prozessbereinigung unerlässlich. Eine andere Methode, um einen linux kill child process durchzuführen, ist die Verwendung von Signalen, ein Thema, das wir in einer späteren Lektion behandeln werden.
Orphan-Prozesse (Verwaiste Prozesse)
Was passiert, wenn ein übergeordneter Prozess beendet wird, bevor sein Kindprozess dies tut? Der Kindprozess wird zu einem "Waisenkind" (Orphan). Da sein ursprünglicher Elternprozess nicht mehr wait aufrufen kann, greift der Kernel ein. Der Waisenprozess wird sofort von einem speziellen Systemprozess, typischerweise init (Prozess-ID 1), adoptiert, der als Vorfahre aller Prozesse gilt. Der init-Prozess übernimmt dann die Rolle des Elternteils und ruft periodisch wait auf, um den Beendigungsstatus aller seiner adoptierten Kinder zu sammeln, was ihnen eine saubere Beendigung ermöglicht.
Zombie-Prozesse
Ein anderes Szenario tritt ein, wenn ein Kindprozess beendet wird, sein Elternteil jedoch noch nicht wait aufgerufen hat. In diesem Zustand wird das Kind zu einem "Zombie"-Prozess. Der Kernel gibt die meisten Ressourcen des Zombies frei, behält jedoch einen Eintrag in der Prozesstabelle. Dieser Eintrag enthält die Prozess-ID und den Beendigungsstatus und wartet darauf, dass der Elternprozess ihn abruft.
Zombie-Prozesse sind bereits tot, verbrauchen daher keine CPU-Zeit. Sie können nicht mit Signalen beendet werden, da sie nicht laufen. Der Vorgang, bei dem der Elternprozess wait aufruft, um einen Zombie zu bereinigen, wird als "Reaping" (Ernten) bezeichnet. Wenn der Elternprozess niemals wait aufruft, können sich diese Zombies ansammeln. Während einige harmlos sind, kann eine große Anzahl die Prozesstabelle füllen und die Erstellung neuer Prozesse verhindern. In Fällen, in denen auch der Elternprozess beendet wird, wird init den Zombie adoptieren und "reapen".
Zombie vs. Orphan-Prozess
Das Verständnis des Unterschieds zwischen einem zombie vs orphan process ist entscheidend für die Diagnose von Prozessproblemen.
- Ein Waisenprozess (Orphan) ist ein aktiver, laufender Prozess, dessen Elternteil gestorben ist. Er wird von
initadoptiert und führt seine Ausführung fort, bis er beendet wird. - Ein Zombie-Prozess ist ein toter Prozess, der seine Ausführung abgeschlossen hat, aber noch einen Eintrag in der Prozesstabelle besitzt. Er wartet darauf, dass sein Elternprozess seinen Exit-Status liest.
Kurz gesagt: Ein Waisenkind ist lebendig, aber vaterlos, während ein Zombie tot ist, aber noch nicht vollständig von seinem Elternteil "geerntet" wurde.