Qu'arrive-t-il à un processus Linux multithread s'il reçoit un signal?

20

Si un processus Unix (Posix) reçoit un signal, un gestionnaire de signal s'exécute.

Que va-t-il lui arriver dans un processus multithread? Quel thread reçoit le signal?

À mon avis, l'API de signal devrait être étendue pour gérer cela (c'est-à-dire que le thread du gestionnaire de signal devrait pouvoir être déterminé), mais en cherchant des informations sur le net, je n'ai trouvé que des flammes d'un an sur la liste de diffusion du noyau Linux et sur différents forums. Si j'ai bien compris, le concept de Linus différait de la norme Posix, et d'abord une couche de compatibilité a été construite, mais maintenant Linux suit le modèle posix.

Quel est l'état actuel?

peterh - Réintégrer Monica
la source
3
Duplicata de stackoverflow.com/questions/11679568/… "pthreads (7) décrit que POSIX.1 requiert tous les threads dans un attribut de partage de processus, y compris les dispositions de signal"
steve
@steve Merci, mais 1) c'est sur un autre site SE 2) cette spécification ne précise pas clairement ce qui se passera exactement. Ce que cela signifie, les gestionnaires de signaux seront appelés sur tous les threads, mais cela me semble un peu surréaliste. 3) Cette réponse ne précise pas quel était le modèle de Linus et pourquoi / comment est-il utilisé actuellement.
peterh

Réponses:

9

L'entrée dans POSIX sur " Génération et livraison de signaux " dans "Justification: Informations générales sur les interfaces système" indique

Les signaux générés pour un processus sont fournis à 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 plus large gamme possible d'implémentations conformes et pour donner aux implémentations la liberté de fournir le signal au thread "le plus simple possible" en cas de différences de facilité de livraison entre les différents threads.

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é à l'aide 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 machine spécifique). les cours de langue sont dirigés sur les threads, tout comme les signaux destinés à un thread spécifique utilisant pthread_kill(3)). Un signal dirigé par le processus peut être délivré à l'un 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.

Et dans pthreads(7):

Les threads ont des paramètres de pile de signaux différents. 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ée dans le noyau 2.6.16).

Du pthreads(3) manuel sur un système OpenBSD (comme exemple d'une approche alternative):

Les gestionnaires de signaux sont normalement exécutés sur la pile du thread en cours d'exécution.

(Je ne sais pas actuellement 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 de cibler des threads uniques distincts par des signaux. Depuis pthreads(7)sur un système Linux:

LinuxThreads ne prend pas en charge la notion de signaux orientés processus: les signaux peuvent être envoyés uniquement à des threads spécifiques.

Kusalananda
la source