Um diese Frage zu beantworten, müssen Sie verstehen, wie Signale an einen Prozess gesendet werden und wie ein Prozess im Kernel vorhanden ist.
Jeder Prozess wird als task_struct
innerhalb des Kernels dargestellt (die Definition befindet sich in der sched.h
Header-Datei und beginnt hier ). Diese Struktur enthält Informationen über den Prozess. zum Beispiel die pid. Die wichtige Information befindet sich in Zeile 1566, in der das zugehörige Signal gespeichert ist. Dies wird nur eingestellt, wenn ein Signal an den Prozess gesendet wird.
Ein toter Prozess oder ein Zombie-Prozess hat noch eine task_struct
. Die Struktur bleibt bestehen, bis der übergeordnete Prozess (natürlich oder durch Adoption) wait()
nach dem Empfang aufgerufen hat SIGCHLD
, seinen untergeordneten Prozess zu ernten. Wenn ein Signal gesendet wird, signal_struct
wird das gesetzt. In diesem Fall spielt es keine Rolle, ob das Signal abfangbar ist oder nicht.
Signale werden jedes Mal ausgewertet, wenn der Prozess ausgeführt wird. Oder um genau zu sein, bevor der Prozess würde laufen. Der Prozess ist dann im TASK_RUNNING
Zustand. Der Kernel führt die schedule()
Routine aus, die den nächsten laufenden Prozess gemäß seinem Planungsalgorithmus bestimmt. Angenommen, dieser Prozess ist der nächste laufende Prozess, wird der Wert von signal_struct
ausgewertet, unabhängig davon, ob ein Wartesignal verarbeitet werden muss oder nicht. Wenn ein Signalhandler manuell definiert wird (über signal()
oder sigaction()
), wird die registrierte Funktion ausgeführt, wenn nicht die Standardaktion des Signals ausgeführt wird. Die Standardaktion hängt vom gesendeten Signal ab.
Beispielsweise SIGSTOP
ändert der Standardhandler des Signals den Status des aktuellen Prozesses in TASK_STOPPED
und wird dann ausgeführt schedule()
, um einen neuen auszuführenden Prozess auszuwählen. Hinweis, SIGSTOP
ist nicht fangbar (wie SIGKILL
), daher gibt es keine Möglichkeit, einen manuellen Signalhandler zu registrieren. Im Falle eines nicht abfangbaren Signals wird die Standardaktion immer ausgeführt.
Zu Ihrer Frage:
Ein nicht mehr funktionierender oder toter Prozess wird vom Scheduler nie wieder als in diesem TASK_RUNNING
Zustand befindlich eingestuft. Daher wird der Kernel niemals den Signalhandler (Standard oder definiert) für das entsprechende Signal ausführen, je nachdem, welches Signal es war. Daher exit_signal
wird das nie wieder eingestellt. Das Signal wird durch Einstellen des signal_struct
Eingangs task_struct
des Prozesses an den Prozess "geliefert" , aber es passiert nichts anderes, da der Prozess nie wieder ausgeführt wird. Es muss kein Code ausgeführt werden. Alles, was vom Prozess übrig bleibt, ist diese Prozessstruktur.
Wenn der übergeordnete Prozess jedoch seine untergeordneten Prozesse erntet wait()
, ist der Exit-Code, den er erhält, derjenige, als der Prozess "anfänglich" gestorben ist. Es spielt keine Rolle, ob ein Signal darauf wartet, verarbeitet zu werden.
kill
selbst 0 oder 1 zurück?