Übergeordneter Prozess - Parent process

Beim Rechnen ist ein übergeordneter Prozess ein Prozess, der einen oder mehrere untergeordnete Prozesse erstellt hat .

Unix-ähnliche Systeme

In Unix-ähnlichen Betriebssystemen wird jeder Prozess außer Prozess 0 (dem Swapper) erstellt, wenn ein anderer Prozess den Systemaufruf fork () ausführt . Der Prozess, der Fork aufgerufen hat, ist der übergeordnete Prozess und der neu erstellte Prozess ist der untergeordnete Prozess . Jeder Prozess (außer Prozess 0) hat einen übergeordneten Prozess, kann jedoch viele untergeordnete Prozesse haben.

Der Betriebssystemkern identifiziert jeden Prozess anhand seiner Prozesskennung. Prozess 0 ist ein spezieller Prozess, der beim Systemstart erstellt wird. Nach dem Verzweigen eines untergeordneten Prozesses (Prozess 1) wird Prozess 0 zum Swapper-Prozess (manchmal auch als " Leerlaufaufgabe " bezeichnet). Prozess 1 , bekannt als init , ist der Vorfahr aller anderen Prozesse im System.

Linux

Im Linux-Kernel , in dem es einen sehr geringen Unterschied zwischen Prozessen und POSIX-Threads gibt, gibt es zwei Arten von übergeordneten Prozessen, nämlich echte übergeordnete und übergeordnete Prozesse. Parent ist der Prozess, der das SIGCHLD- Signal bei Beendigung des Kindes empfängt , während Real Parent der Thread ist, der diesen untergeordneten Prozess in einer Multithread-Umgebung tatsächlich erstellt hat. Für einen normalen Prozess sind diese beiden Werte gleich, aber für einen POSIX-Thread, der als Prozess fungiert, können diese beiden Werte unterschiedlich sein.

Zombie-Prozesse

Das Betriebssystem verwaltet eine Tabelle, die jeden Prozess anhand seiner Prozesskennung (im Allgemeinen als " pid " bezeichnet) mit den für seine Funktion erforderlichen Daten verknüpft . Während der Lebensdauer eines Prozesses können solche Daten Speichersegmente enthalten, die für den Prozess bestimmt sind, die Argumente, mit denen er aufgerufen wurde, Umgebungsvariablen , Zähler für die Ressourcennutzung, Benutzer-ID, Gruppen-ID und Gruppensatz sowie möglicherweise andere Arten von Informationen.

Wenn ein Prozeß seine Ausführung beendet, entweder durch Aufruf Ausgang (auch implizit , wenn durch ein Ausführen return Befehls von der Hauptfunktion) oder durch ein Empfangssignal , das abrupt zu beenden , bewirkt, aus den Betriebssystemversionen meisten Ressourcen und Informationen zu Dieser Prozess behält jedoch die Daten zur Ressourcennutzung und zum Beendigungsstatuscode bei , da ein übergeordneter Prozess möglicherweise wissen möchte, ob dieses untergeordnete Element erfolgreich ausgeführt wurde (indem Standardfunktionen zum Decodieren des Beendigungsstatuscodes verwendet wurden) und wie viele Systemressourcen es enthält während seiner Ausführung verbraucht.

Standardmäßig geht das System davon aus, dass der übergeordnete Prozess zum Zeitpunkt der Beendigung des Kindes tatsächlich an solchen Informationen interessiert ist, und sendet dem Elternteil daher das Signal SIGCHLD , um darauf hinzuweisen , dass einige Daten über ein Kind erfasst werden müssen. Eine solche Erfassung erfolgt durch Aufrufen einer Funktion der Wait- Familie (entweder wait selbst oder einer ihrer Verwandten, wie waitpid , waitid oder wait4 ). Sobald diese Sammlung erstellt wurde, gibt das System die letzten Informationen über den untergeordneten Prozess frei und entfernt seine PID aus der Prozesstabelle. Wenn der übergeordnete Prozess jedoch beim Sammeln der Daten des Kindes verweilt (oder dies überhaupt nicht tut), hat das System keine andere Wahl, als die PID- und Beendigungsdaten des Kindes unbegrenzt in der Prozesstabelle zu belassen.

Ein solcher abgebrochener Prozess, dessen Daten nicht erfasst wurden , wird im UNIX-Sprachgebrauch als Zombie-Prozess oder einfach als Zombie bezeichnet . Der Name ist eine humorvolle Analogie, da der beendete Prozess als "nicht mehr lebendig" oder "tot" betrachtet wird - da er wirklich nicht mehr funktioniert - und ein verweilender toter Prozess, der in der "Welt der lebenden" Prozesse immer noch "inkarniert" ist - der Prozess Tabelle - das ist also eigentlich "Untoter" oder "Zombie".

Zombie-Prozesse können auf Systemen mit begrenzten Ressourcen oder mit Prozesstabellen mit begrenzter Größe Probleme verursachen, da die Erstellung neuer, aktiver Prozesse durch den Mangel an Ressourcen verhindert werden kann, die noch von langlebigen Zombies verwendet werden.

Es ist daher eine gute Programmierpraxis in jedem Programm, das untergeordnete Prozesse hervorbringen könnte, um Code zu haben, um die Bildung langlebiger Zombies von seinen ursprünglichen Kindern zu verhindern. Der naheliegendste Ansatz besteht darin, Code zu haben, der irgendwo wartet, oder einen seiner Verwandten, nachdem ein neuer Prozess erstellt wurde. Wenn erwartet wird, dass das Programm viele untergeordnete Prozesse erstellt, die möglicherweise asynchron ausgeführt werden und in einer unvorhersehbaren Reihenfolge beendet werden, ist es im Allgemeinen sinnvoll , einen Handler für das SIGCHLD- Signal zu erstellen , der eine der Funktionen der Familie wait in einer Schleife aufruft, bis kein untergeordnetes untergeordnetes Element mehr vorhanden ist Daten bleiben erhalten. Es ist möglich, dass der übergeordnete Prozess die Beendigung seiner untergeordneten Elemente vollständig ignoriert und dennoch keine Zombies erstellt. Dies erfordert jedoch die explizite Definition eines Handlers für SIGCHLD durch einen Aufruf zur Sigaktion mit dem speziellen Optionsflag SA_NOCLDWAIT .

Verwaiste Prozesse

Verwaiste Prozesse sind eine entgegengesetzte Situation zu Zombie-Prozessen und beziehen sich auf den Fall, in dem ein übergeordneter Prozess vor seinen untergeordneten Prozessen beendet wird, die als "verwaist" bezeichnet werden. Im Gegensatz zur asynchronen Benachrichtigung von Kind zu Eltern, die beim Beenden eines untergeordneten Prozesses (über das SIGCHLD- Signal) erfolgt, werden untergeordnete Prozesse nicht sofort benachrichtigt, wenn ihr übergeordneter Prozess beendet ist . Stattdessen definiert das System das Feld "übergeordnete PID" in den Daten des untergeordneten Prozesses einfach neu als den Prozess, der der "Vorfahr" jedes anderen Prozesses im System ist, dessen PID im Allgemeinen den Wert 1 (eins) hat und dessen Name ist traditionell "init". Daher wurde gesagt, dass init jeden verwaisten Prozess auf dem System "übernimmt".

Eine etwas verbreitete Annahme von Programmierern, die neu in UNIX sind, war, dass die untergeordneten Prozesse eines Beendigungsprozesses vom unmittelbaren übergeordneten Prozess dieses Prozesses übernommen werden (daher die "Großeltern" dieser untergeordneten Prozesse). Eine solche Annahme war falsch - es sei denn natürlich, dass "Großeltern" der Init selbst waren.

Nach dem Linux-Kernel 3.4 ist dies nicht mehr der Fall. Tatsächlich können Prozesse den Systemaufruf prctl () mit der Option PR_SET_CHILD_SUBREAPER ausgeben. Infolgedessen werden sie, nicht Prozess Nr. 1, zum übergeordneten Element ihrer verwaisten Nachkommenprozesse. Dies ist die Arbeitsweise moderner Service-Manager und Dienstprogramme zur Daemon-Überwachung, einschließlich systemd, upstart und nosh service manager.

Dies ist eine Zusammenfassung der Handbuchseite, in der Folgendes berichtet wird:

Ein Subreaper erfüllt die Rolle von init (1) für seine Nachkommenprozesse. Wenn ein Prozess verwaist ist (dh sein unmittelbares übergeordnetes Element wird beendet), wird dieser Prozess an den nächsten noch lebenden Vorfahren-Subreaper repariert. Anschließend geben Aufrufe von getppid () im verwaisten Prozess jetzt die PID des Subreaper-Prozesses zurück. Wenn das Orphan beendet wird, empfängt der Subreaper-Prozess ein SIGCHLD-Signal und kann (2) auf den Prozess warten um seinen Beendigungsstatus zu ermitteln.

Verweise

Dieser Artikel basiert auf Material, das vor dem 1. November 2008 aus dem Free Online Dictionary of Computing entnommen und unter den "Relicensing" -Bedingungen der GFDL , Version 1.3 oder höher, aufgenommen wurde.