Ich habe das Verhalten des Linux-Kernels schon seit einiger Zeit untersucht, und mir war immer klar, dass:
Wenn ein Prozess stirbt, werden alle seine Kinder an den
init
Prozess (PID 1) zurückgegeben, bis sie schließlich sterben.
Kürzlich hat mir jedoch jemand mit viel mehr Erfahrung als ich mit dem Kernel gesagt, dass:
Wenn ein Prozess beendet wird, sterben auch alle seine untergeordneten Elemente (es sei denn, Sie verwenden,
NOHUP
in welchem Fall sie zurückkehreninit
).
Auch wenn ich das nicht glaube, habe ich dennoch ein einfaches Programm geschrieben, um sicherzugehen. Ich weiß, dass ich mich sleep
bei Tests nicht auf time ( ) verlassen sollte , da alles von der Prozessplanung abhängt, aber für diesen einfachen Fall denke ich, dass das ausreichend ist.
int main(void){
printf("Father process spawned (%d).\n", getpid());
sleep(5);
if(fork() == 0){
printf("Child process spawned (%d => %d).\n", getppid(), getpid());
sleep(15);
printf("Child process exiting (%d => %d).\n", getppid(), getpid());
exit(0);
}
sleep(5);
printf(stdout, "Father process exiting (%d).\n", getpid());
return EXIT_SUCCESS;
}
Hier ist die Ausgabe des Programms mit dem zugehörigen ps
Ergebnis bei jedem printf
Gespräch:
$ ./test &
Father process spawned (435).
$ ps -ef | grep test
myuser 435 392 tty1 ./test
Child process spawned (435 => 436).
$ ps -ef | grep test
myuser 435 392 tty1 ./test
myuser 436 435 tty1 ./test
Father process exiting (435).
$ ps -ef | grep test
myuser 436 1 tty1 ./test
Child process exiting (436).
Nun, wie Sie sehen können, verhält sich dies so, wie ich es erwartet hätte. Der Waisenprozess (436) wird an init
(1) zurückgegeben, bis er stirbt.
Gibt es jedoch ein UNIX-basiertes System, auf dem dieses Verhalten nicht standardmäßig angewendet wird? Gibt es ein System, bei dem der Tod eines Prozesses sofort den Tod aller seiner Kinder auslöst?
nohup
mitdisown
.disown
ist eine integrierte Shell, die einen laufenden Job aus der Jobtabelle entfernt (unter Verwendung eines Arguments wie%1
), und der wichtigste nützliche Nebeneffekt ist, dass die Shell kein SIGHUP an den Unterprozess sendet.nohup
ist ein externes Dienstprogramm, das SIGHUP ignoriert (und nur wenige andere Aktionen ausführt) und dann den über die Befehlszeile übergebenen Befehl startet.nohup
, wird das Signal ignoriert, bevor esexec
der Befehl ist.Dies ist korrekt, wenn der Prozess ein Sitzungsleiter ist. Wenn ein Sitzungsleiter stirbt, wird ein SIGHUP an alle Mitglieder dieser Sitzung gesendet. In der Praxis bedeutet das seine Kinder und ihre Nachkommen.
Ein Prozess macht sich selbst zum Sitzungsleiter, indem er aufruft
setsid
. Muscheln verwenden dies.quelle
fork
, übergeordneten Prozesssetsid
beenden) und ein anderes Kind in diese neue Sitzung eingegabelt. Als jedoch der übergeordnete Prozess (neuer Sitzungsleiter) starb, erhielt das Kind keine SEHENSWÜRDIGKEIT und wurde angefügt,init
bis es schließlich beendet wurde.setpgid(2)
Manpage: Wenn eine Sitzung ein steuerndes Terminal hat und das CLOCAL-Flag für dieses Terminal nicht gesetzt ist und ein Terminal-Hangup auftritt, wird dem Sitzungsleiter ein SIGHUP gesendet. Wenn der Sitzungsleiter abreist, wird auch ein SIGHUP-Signal an jeden Prozess in der Vordergrundprozessgruppe des steuernden Terminals gesendet.Was über den Plakaten steht, ist, dass die Kinder nicht sterben, die Eltern sie töten (oder ihnen ein Signal senden, bei dem sie terminieren). Sie können also das haben, wonach Sie fragen, wenn Sie den Elternteil so programmieren, dass er (1) alle seine Kinder aufzeichnet und (2) ein Signal an alle seine Kinder sendet.
Dies ist, was die Shell tut, und es sollte sein, was Ihr übergeordneter Prozess tut. Möglicherweise muss das HUP-Signal im übergeordneten Element abgefangen werden, damit Sie noch genügend Kontrolle haben, um die Kinder zu töten.
quelle
Ich vermisse ein bisschen in den Antworten, die etwas mit sterbenden Eltern zu tun haben: Wenn ein Prozess auf eine Pipe schreibt, für die es keinen Lesevorgang mehr gibt, erhält er eine SIGPIPE. Die Standardaktion für SIGPIPE ist die Beendigung.
Dies kann tatsächlich zum Absterben von Prozessen führen. Tatsächlich ist dies die Standardmethode, mit der das Programm
yes
stirbt.Wenn ich ausführe
Auf meinem System lautet die Antwort
und 141 ist in der Tat 128 + SIGPIPE:
von
man 7 signal
.quelle