pthreads(7)
beschreibt, dass POSIX.1 alle Threads in einem Prozess Share-Attribute benötigt, einschließlich:
- Signaldispositionen
POSIX.1 erfordert auch, dass einige Attribute eindeutig sind für jeden Thread, einschließlich:
-
Signalmaske (
pthread_sigmask(3)
) -
alternativer Signalstapel (
sigaltstack(2)
)
complete_signal
des Linux-Kernels Routine hat den folgenden Codeblock -- die Kommentare sind sehr nützlich:
/*
* Now find a thread we can wake up to take the signal off the queue.
*
* If the main thread wants the signal, it gets first crack.
* Probably the least surprising to the average bear.
*/
if (wants_signal(sig, p))
t = p;
else if (!group || thread_group_empty(p))
/*
* There is just one thread and it does not need to be woken.
* It will dequeue unblocked signals before it runs again.
*/
return;
else {
/*
* Otherwise try to find a suitable thread.
*/
t = signal->curr_target;
while (!wants_signal(sig, t)) {
t = next_thread(t);
if (t == signal->curr_target)
/*
* No thread needs to be woken.
* Any eligible threads will see
* the signal in the queue soon.
*/
return;
}
signal->curr_target = t;
}
/*
* Found a killable thread. If the signal will be fatal,
* then start taking the whole group down immediately.
*/
if (sig_fatal(p, sig) &&
!(signal->flags & SIGNAL_GROUP_EXIT) &&
!sigismember(&t->real_blocked, sig) &&
(sig == SIGKILL || !p->ptrace)) {
/*
* This signal will be fatal to the whole group.
*/
Sie sehen also Sie sind dafür verantwortlich, wohin die Signale geliefert werden:
Wenn Ihr Prozess die Disposition eines Signals auf SIG_IGN
gesetzt hat oder SIG_DFL
, dann wird das Signal für alle Threads ignoriert (oder standardmäßig -- kill, core oderignore).
Wenn Ihr Prozess die Disposition eines Signals auf eine bestimmte Behandlungsroutine festgelegt hat, können Sie steuern, welcher Thread die Signale empfängt, indem Sie bestimmte Thread-Signalmasken mit pthread_sigmask(3)
manipulieren . Sie können einen Thread ernennen, um sie alle zu verwalten, oder einen Thread pro Signal erstellen, oder eine beliebige Mischung dieser Optionen für bestimmte Signale, oder Sie verlassen sich auf das aktuelle Standardverhalten des Linux-Kernels, das Signal an den Haupt-Thread zu liefern.
Einige Signale sind jedoch speziell gemäß signal(7)
Manpage:
Ein Signal kann für einen Prozess als Ganzes (z. B. wenn es mit kill(2) gesendet wird) oder für einen bestimmten Thread (z. B. bestimmte Signale wie SIGSEGV und SIGFPE, die als Folge der Ausführung von a generiert werden) generiert (und somit anstehend) werden spezifische maschinensprachliche Anweisungen sind Thread-gerichtet, ebenso wie Signale, die mit pthread_kill(3) auf einen bestimmten Thread abzielen. Ein prozessgerichtetes Signal kann an jeden der Threads geliefert werden, der derzeit das Signal nicht blockiert hat. Wenn mehr als einer der Threads das Signal nicht blockiert hat, dann wählt der Kernel einen beliebigen Thread aus, an den das Signal geliefert werden soll.
Dies ist leicht nuanciert, je nachdem, welche Version des Linux-Kernels Sie verwenden.
Unter der Annahme von 2.6 Posix-Threads und wenn Sie über das Betriebssystem sprechen, das SIGTERM oder SIGHUP sendet, wird das Signal an den Prozess gesendet, der vom Root-Thread empfangen und verarbeitet wird. Mit POSIX-Threads können Sie SIGTERM auch an einzelne Threads senden, aber ich vermute, Sie fragen danach, was passiert, wenn das Betriebssystem das Signal an den Prozess sendet.
In 2.6 bewirkt SIGTERM, dass untergeordnete Threads "sauber" beendet werden, während in 2.4 untergeordnete Threads in einem unbestimmten Zustand gelassen wurden.