In einigen Antworten wird das Wort „Subreaper“ verwendet. Bei der Google-Suche werden auch Einträge angezeigt, in denen das Wort „nur verwendet“ wird.
Wie kann ich verstehen, was ein „Subreaper“ ist?
Akzeptierte Antwort:
Dies wurde im Linux-Kernel 3.4 als Flag des Systemaufrufs prctl() implementiert.
Aus prctl(2)
Handbuchseite:
[…] Ein Subreaper erfüllt die Rolle von init(1)
für seine Nachkommen
Prozesse. Nach Beendigung eines verwaisten Prozesses (d. h., sein
unmittelbarer Elternteil wurde bereits beendet) und als einen
Subreaper aufweisend gekennzeichnet, erhält der nächste noch lebende Vorfahren-Subreaper ein SIGCHLD
signalisieren und wait(2)
können auf den Prozess, um seinen
Beendigungsstatus zu ermitteln.
Ein Prozess kann sich mit prctl(PR_SET_CHILD_SUBREAPER)
als Subreaper definieren . Wenn ja, ist es nicht init
(PID 1), der zum Elternteil von verwaisten Kindprozessen wird, wird stattdessen der nächste lebende Großelternteil, der als Subreaper gekennzeichnet ist, zum neuen Elternteil. Wenn es keinen lebenden Großelternteil gibt, init
tut.
Der Grund für die Implementierung dieses Mechanismus war, dass Userspace Service Manager/Supervisors (wie upstart
, systemd
) müssen ihre gestarteten Dienste nachverfolgen. Viele Dienste werden durch Double-Forking dämonisiert und implizit der PID 1 neu zugeordnet. Der Dienstverwalter kann den SIGCHLD
nicht mehr empfangen Signale für sie und ist nicht mehr dafür verantwortlich, die Kinder mit wait()
zu ernten . Alle Informationen über die Kinder gehen in dem Moment verloren, in dem PID 1 die Reparent-Prozesse bereinigt. Jetzt kann sich ein Service-Manager-Prozess als eine Art „Sub-Init“ kennzeichnen und kann nun als übergeordneter Prozess für alle verwaisten Prozesse verbleiben, die von den gestarteten Diensten erstellt wurden. Alle SIGCHLD
Signale werden an den Service Manager übermittelt.
Unter Linux wird ein Daemon normalerweise durch zweimaliges Forken erstellt, wobei der Zwischenprozess nach dem Forken des Enkels beendet wird. Dies ist eine gängige Technik, um Zombie-Prozesse zu vermeiden. Das Init-Skript ruft ein Kind auf. Dieses Kind gabelt erneut und steigt somit sofort aus. Das Enkelkind wird von init
adoptiert , die kontinuierlich wait()
aufruft um den Exit-Status seiner Kinder zu sammeln, um Zombies zu vermeiden. Mit dem Konzept der Subreapers wird nun der Userspace Service Manager zum neuen Parent, anstatt init
.