pthreads(7)
décrit que POSIX.1 requiert tous les threads dans les attributs de partage de processus, y compris :
- signaler les dispositions
POSIX.1 exige également que certains attributs soient distincts pour chaque fil, y compris :
-
masque de signal (
pthread_sigmask(3)
) -
pile de signaux alternative (
sigaltstack(2)
)
Le complete_signal
du noyau Linux routine a le bloc de code suivant -- les commentaires sont très utiles :
/*
* 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.
*/
Donc, vous voyez que vous sont en charge de l'endroit où les signaux sont livrés :
Si votre processus a défini la disposition d'un signal sur SIG_IGN
ou SIG_DFL
, alors le signal est ignoré (ou par défaut -- kill, core ou ignore) pour tous les threads.
Si votre processus a défini la disposition d'un signal sur une routine de gestionnaire spécifique, vous pouvez contrôler quel thread recevra les signaux en manipulant des masques de signal de thread spécifiques à l'aide de pthread_sigmask(3)
. Vous pouvez nommer un thread pour les gérer tous, ou créer un thread par signal, ou n'importe quel mélange de ces options pour des signaux spécifiques, ou vous fier au comportement par défaut actuel du noyau Linux de fournir le signal au thread principal.
Certains signaux sont cependant spéciaux selon le signal(7)
page de manuel :
Un signal peut être généré (et donc en attente) pour un processus dans son ensemble (par exemple, lorsqu'il est envoyé à l'aide de kill(2)) ou pour un thread spécifique (par exemple, certains signaux, tels que SIGSEGV et SIGFPE, générés à la suite de l'exécution d'un des instructions spécifiques en langage machine sont dirigées vers les threads, tout comme les signaux destinés à un thread spécifique à l'aide de pthread_kill(3)). Un signal dirigé par le processus peut être délivré à n'importe lequel des threads qui n'a pas actuellement le signal bloqué. Si plus d'un des threads a le signal débloqué, alors le noyau choisit un thread arbitraire auquel délivrer le signal.
Ceci est légèrement nuancé, en fonction de la version du noyau Linux que vous utilisez.
En supposant que les threads posix 2.6, et si vous parlez du système d'exploitation envoyant SIGTERM ou SIGHUP, le signal est envoyé au processus, qui est reçu et géré par le thread racine. En utilisant les threads POSIX, vous pouvez également envoyer SIGTERM à des threads individuels, mais je suppose que vous demandez ce qui se passe lorsque le système d'exploitation envoie le signal au processus.
Dans 2.6, SIGTERM entraînera la sortie "propre" des threads enfants, alors qu'en 2.4, les threads enfants étaient laissés dans un état indéterminé.