L'entrée dans POSIX sur "Signal Generation and Delivery" dans "Rationale :System Interfaces General Information" indique
Les signaux générés pour un processus sont livrés à un seul thread. Ainsi, si plus d'un thread est éligible pour recevoir un signal, il faut en choisir un. Le choix des threads est entièrement laissé à l'implémentation à la fois pour permettre la gamme la plus large possible d'implémentations conformes et pour donner aux implémentations la liberté de délivrer le signal au thread "le plus simple possible" en cas de différences de facilité de livraison entre les différents threads.
A partir du signal(7)
manuel sur un système Linux :
Un signal peut être généré (et donc en attente) pour un processus dans son ensemble (par exemple, lorsqu'il est envoyé en utilisant
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'une instruction spécifique en langage machine sont dirigés vers le thread, tout comme les signaux ciblés sur un thread spécifique à l'aide depthread_kill(3)
). Un signal dirigé par le processus peut être délivré à l'un quelconque des threads dont le signal n'est pas actuellement bloqué. Si plus d'un des threads a le signal débloqué, alors le noyau choisit un thread arbitraire auquel délivrer le signal.
Et en pthreads(7)
:
Les threads ont des paramètres de pile de signaux alternatifs distincts. Cependant, les paramètres de pile de signaux alternatifs d'un nouveau thread sont copiés à partir du thread qui l'a créé, de sorte que les threads partagent initialement une pile de signaux alternative (corrigé dans le noyau 2.6.16).
Du pthreads(3)
manuel sur un système OpenBSD (comme exemple d'approche alternative) :
Les gestionnaires de signaux sont normalement exécutés sur la pile du thread en cours d'exécution.
(Je ne sais actuellement pas comment cela est géré lorsque plusieurs threads s'exécutent simultanément sur une machine multiprocesseur)
L'ancienne implémentation LinuxThread des threads POSIX permettait uniquement à des threads uniques distincts d'être ciblés par des signaux. À partir de pthreads(7)
sur un système Linux :
LinuxThreads ne prend pas en charge la notion de signaux dirigés par processus :les signaux ne peuvent être envoyés qu'à des threads spécifiques.
En prolongeant la réponse acceptée, il y a une vue plus pratique, ce que j'ai trouvé ici.
L'essentiel est le suivant :
Les gestionnaires de signaux sont par processus, mais les masques de signaux sont par thread.
- Ainsi, si nous installons/désinstallons un gestionnaire de signal (avec signal() ou sigaction()) sur n'importe quel thread, cela les affectera tous.
- Si un processus reçoit un signal, le gestionnaire ne sera exécuté que sur un seul thread. Ce fil est sélectionné de manière pseudo-aléatoire parmi eux, dont le masque de signal l'accepte. Mes expériences montrent que c'est toujours le thread avec le moins de pid.
- Les signaux envoyés à n'importe quel thread sont considérés comme des signaux envoyés au processus principal. Ainsi, si un thread reçoit un signal, il est tout à fait possible qu'un autre thread exécute le gestionnaire. Mieux si nous voyons cela comme si les threads (identifiés par
tid
s, thread ids) seraient considérés comme des processus masqués (identifiés parpid
s), et les signaux envoyés à untid
serait transmis à leurpid
. - Pour l'exécution d'un gestionnaire de signal, dans son masque de signal, le numéro de signal donné est automatiquement masqué. Cela permet d'empêcher l'exécution du gestionnaire de signaux empilés dans une salve de signaux. Cela peut être changé avec le
SA_NODEFER
drapeau dusigaction(...)
appeler. - (3) et (4) résultent que dans le cas d'une rafale de signal, le système distribue les gestionnaires de signal probablement le plus parallèlement.
- Cependant, si nous avons configuré la signalisation avec
SA_NODEFER
, toujours le même thread recevra le signal et ils s'empileront .