Ist es möglich, einen Prozess zu übernehmen?

Lesezeit: 8 Minuten

Benutzer-Avatar
alk

Prozess A fork()s Prozess B.

Prozess A stirbt und daher init nimmt B an.

Ein Watchdog erstellt Prozess C.

Ist es irgendwie möglich, dass C B von adoptiert? init?


Aktualisieren:

Oder wäre es sogar möglich, dass C B direkt adoptiert (wenn A stirbt), wenn C vor dem Tod von A geschaffen wurde, ohne init Zwischenelternteil von B werden?


Update-1:

Ich würde mich auch über Kommentare freuen, warum die Möglichkeit, einen Prozess auf die von mir beschriebene Weise zu übernehmen, eine schlechte Sache oder schwierig bis unmöglich zu implementieren wäre.


Update-2 – Der Anwendungsfall (Eltern und Kinder beziehen sich auf Prozess(e)):

Ich habe eine App, die einen Elternteil verwendet, um eine ganze Reihe von Kindern zu verwalten, die sich auf die Verwaltungseinrichtung des Elternteils verlassen. Um seine Arbeit zu erledigen, verlässt sich der Elternteil darauf, dass er von der Kündigung eines Kindes benachrichtigt wird, was durch den Erhalt der zugehörigen Nachricht erfolgt SIGCHLD Signal.

Wenn der Elternteil selbst aufgrund eines Unfalls stirbt (einschließlich Segfaulting), muss ich die gesamte “Familie” neu starten, da es jetzt unmöglich ist, etwas bei der Beendigung eines Kindes auszulösen (was auch auf einen Segfault zurückzuführen sein könnte).

In einem solchen Fall muss ich alle untergeordneten Elemente herunterfahren und einen Neustart des gesamten Systems durchführen.

Ein möglicher Ansatz, um diese Situation zu vermeiden, wäre es, einen Ersatzprozess zu haben, der die Rolle des toten Elternteils übernehmen könnte … – wenn er die Stiefkinder wieder erhalten könnte SIGCHLD Signale!

  • Die Kinder könnten sich selbst zu Fall bringen, wenn sie nur das “gelesene” Ende einer Pfeife erben, die von den Eltern hergestellt wurde. Das ‘Lesen’-Ende wird nach dem Tod des Elternteils lesbar (für EOF) auswählen, ein IO-Ereignis, das jedes Kind abfangen und auf das es reagieren könnte.

    – Pilkrähe

    17. Mai 2012 um 16:56 Uhr


  • Dieses Problem ist, dass ich die Kinder nicht zu Fall bringen möchte. Ich hätte gerne die Möglichkeit, den verstorbenen Elternteil (in Bezug auf die Möglichkeit, seine SIGCHLD zu erhalten, falls er endet) durch einen Stiefelternprozess zu ersetzen. @pilcrow

    – alk

    18. Mai 2012 um 20:49 Uhr

  • In meinem obigen Kommentar dies “… erhalten ihr SIGCHLD …” sollte lesen “… erhalten das SIGCHLD ihrer Kinder …“.

    – alk

    8. August 2015 um 13:31 Uhr


Benutzer-Avatar
Nicolas Wilson

Nein, definitiv nicht möglich. Ohne einige üble Rennbedingungen war es auch nicht umsetzbar. Die POSIX-Jungs, die diese APIs erstellen, würden niemals etwas mit einer inhärenten Race-Condition erstellen, also selbst wenn Sie sich nicht darum kümmern, wird Ihr Kernel es in absehbarer Zeit nicht bekommen.

Ein Problem besteht darin, dass PIDs wiederverwendet werden (sie sind eine knappe Ressource!), und Sie können auch keine Handhabe oder Sperre für eine bekommen; es ist nur eine Zahl. Angenommen, Sie haben irgendwo in Ihrem Code eine Variable, in die Sie die PID des Prozesses einfügen, den Sie neu zuordnen möchten. Dann rufst du an make_this_a_child_of_me(thepid). Was würde dann passieren? In der Zwischenzeit hat sich der andere Prozess möglicherweise beendet und thepid geändert, um auf einen anderen Prozess zu verweisen! Hoppla. Es kann keine Möglichkeit geben, a bereitzustellen make_this_a_child_of_me API ohne große Umstrukturierung der Art und Weise, wie Unix Prozesse verarbeitet.

Beachten Sie, dass die ganze Sache mit waitDie Verwendung von untergeordneten PIDs dient genau dazu, dieses Problem zu verhindern: Ein Zombie-Prozess existiert immer noch in der Prozesstabelle, um zu verhindern, dass seine PID wiederverwendet wird. Der Elternteil kann dann über seine PID auf sein Kind verweisen, in der Gewissheit, dass der Prozess nicht beendet wird und die Kind-PID wiederverwendet wird. Wenn das Kind aussteigt, wird seine PID reserviert, bis das Elternteil SIGCHLD abfängt oder darauf wartet. Sobald der Prozess geerntet ist, steht seine PID sofort zur Verfügung, damit andere Programme sie verwenden können, wenn sie forken, aber der Elternteil weiß garantiert bereits davon.

Antwort auf Aktualisierung: Betrachten Sie ein komplizierteres Schema, bei dem Prozesse ihrem nächsten Vorfahren neu zugeordnet werden. Natürlich ist dies nicht in jedem Fall möglich, da Sie häufig einen Weg suchen, ein Kind zu verleugnen, um sicherzustellen, dass Sie Zombies vermeiden. init erfüllt diese Rolle sehr gut. Es muss also eine Möglichkeit für einen Prozess geben, anzugeben, ob er beabsichtigt, seine Enkelkinder (oder niedrigere) zu adoptieren oder nicht. Das Problem bei diesem Design ist genau dasselbe wie in der ersten Situation: Sie still Rennbedingungen erhalten.

Wenn es wieder von pid erledigt wird, setzt sich der Großelternteil einer Race-Bedingung aus: Nur der Elternteil kann eine PID ernten, also weiß nur der Elternteil wirklich, zu welchem ​​​​Prozess eine PID gehört. Da der Großelternteil nicht ernten kann, kann er nicht sicher sein, dass sich der Enkelprozess nicht von dem geändert hat, den er übernehmen (oder ablehnen, je nachdem, wie die hypothetische API funktionieren würde) beabsichtigt hat. Denken Sie daran, dass auf einem stark ausgelasteten Computer nichts dagegen spricht, dass ein Prozess minutenlang von der CPU genommen wird, und sich in dieser Zeit eine ganze Last geändert haben könnte! Nicht ideal, aber POSIX muss dafür Rechenschaft ablegen.

Nehmen wir zum Schluss an, dass diese API nicht mit PID funktioniert, sondern nur allgemein sagt: “Sende alle Enkelkinder an mich” oder “Sende sie an Init”. Wenn es aufgerufen wird, nachdem die untergeordneten Prozesse erzeugt wurden, erhalten Sie die Race-Bedingungen wie zuvor. Wenn es vorher aufgerufen wird, dann ist das Ganze nutzlos: Sie sollten in der Lage sein, Ihre Anwendung ein wenig umzustrukturieren, um das gleiche Verhalten zu erhalten. Das heißt, wenn Sie wissen, bevor Sie mit dem Spawnen von untergeordneten Prozessen beginnen, wer der Elternteil von wem sein sollte, warum können Sie sie dann nicht gleich von Anfang an richtig herum erstellen? Pipes und IPC sind wirklich in der Lage, alle erforderlichen Arbeiten zu erledigen.

  • Danke für deine Erklärungen. Ich verstehe jedoch, dass es nicht machbar ist, einfach die Elternschaft eines Prozesses zu übernehmen. Aber für den zweiten Weg (erwähnt unter Update In meiner Frage) könnte es eine Möglichkeit geben, einen bestehenden Prozess als Ersatzprozess zu registrieren, um (in Bezug auf die Elternschaft) einzuspringen, falls ein anderer Prozess stirbt, sodass seine Kinder dann nicht von adoptiert werden init aber durch (den zuvor registrierten) Spare-Prozess.

    – alk

    11. Mai 2012 um 14:32 Uhr


  • Nochmals vielen Dank für die Mitteilung Ihrer Gedanken. In Bezug auf die Neubeelterung von Großeltern sehe ich sicherlich, dass dies nicht zu einem Standardverhalten gemacht werden kann, da viele bestehende Implementierungen (und Muster) darauf angewiesen sind, dass Kinder ihre Eltern verlieren, um von init adoptiert zu werden.

    – alk

    16. Mai 2012 um 15:43 Uhr

  • Wie init ist ein Prozess, der tut Kinder adoptieren (was vom Kernel durchgeführt wird), warum also nicht dem Kernel erlauben, diesen Waisenkindern einen anderen Prozess als init zuzuweisen. Ich habe tatsächlich über einen Ansatz nachgedacht, wie Sie ihn in Ihrem Absatz erwähnt haben, beginnend mit “schicke alle Enkel zu mir” oder “schick sie zu init“. Bitte lesen Sie Update-2 in meiner Frage für Details zu dem Anwendungsfall, mit dem ich konfrontiert bin.

    – alk

    16. Mai 2012 um 15:47 Uhr

  • Gute Argumente. Im Linux-Kernel jedoch Kind und Eltern task_struct Verweise aufeinander behalten, sodass es technisch möglich wäre, dass ein Großelternteil ein Kind erbt, wenn der Elternteil stirbt.

    – Maxim Egorushkin

    16. Mai 2012 um 16:00 Uhr

  • Beachten Sie, dass z. B. Linux (seit Kernel 3.4) neben “re-parent to init” eine weitere Möglichkeit hat, einen Prozess neu zu parenten, siehe stackoverflow.com/questions/6476452/… , (aber immer noch keine Möglichkeit, einen Prozess zu übernehmen wieder von init)

    – Nr

    22. April 2015 um 11:08 Uhr


Nein, es gibt keine Möglichkeit, die Neuzuordnung auf die von Ihnen beschriebene Weise zu erzwingen.

  • Obwohl es mir schwer fällt zu akzeptieren, was Sie schreiben, akzeptiere ich Ihre Antwort … 😉 – jedenfalls frage ich mich, ob es gute Gründe gibt, eine solche Möglichkeit nicht zur Verfügung zu haben. Oder ist es nur, weil es niemand braucht, also hat es (noch) niemand implementiert? @als

    – alk

    10. Mai 2012 um 15:52 Uhr


  • @alk: Wenn es Ihnen schwer fällt, es zu akzeptieren, akzeptieren Sie es nicht, lassen Sie das q sein oder fügen Sie vielleicht ein Kopfgeld hinzu.

    – Alok Speichern

    10. Mai 2012 um 15:57 Uhr

  • Sie haben Recht. Ich werde Ihre Antwort nicht akzeptieren, da dies vielleicht jemanden dazu motivieren könnte, diese Frage zu kommentieren. @als

    – alk

    11. Mai 2012 um 9:24 Uhr

Ich kenne keinen guten Weg, dies zu tun, aber ein Grund dafür ist, dass ein laufender Prozess für sich allein stehen oder einem übergeordneten Prozess eine Fähigkeit hinzufügen kann. Die Adoption würde als Ergebnis eines Ereignisses erfolgen, das dem (noch nicht) Kind, aber nicht dem Elternteil bekannt ist. Das werdende Kind würde ein Signal an die Eltern senden. Der Elternteil würde das Kind adoptieren (oder nicht). Sobald der Eltern-Kind-Prozess Teil des Elternteils ist, wäre er in der Lage, auf das Ereignis zu reagieren, während keiner auf das Ereignis reagieren könnte, wenn er alleine steht.

Dieses Docking-Verhalten könnte in die Apps codiert werden, aber ich weiß nicht, wie man es in Echtzeit macht. Es gibt andere Möglichkeiten, dieselbe Funktionalität zu erreichen. Ein Elternteil, der das Andocken von Kindern akzeptieren könnte, könnte seine Funktionalität auf neuartige Weise erweitern lassen, die dem Elternteil zuvor nicht bekannt war.

1347110cookie-checkIst es möglich, einen Prozess zu übernehmen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy