La entrada en POSIX sobre "Generación y entrega de señales" en "Fundamento:información general de las interfaces del sistema" dice
Las señales generadas para un proceso se entregan a un solo hilo. Por lo tanto, si más de un subproceso es elegible para recibir una señal, se debe elegir uno. La elección de los subprocesos se deja enteramente en manos de la implementación, tanto para permitir la gama más amplia posible de implementaciones conformes como para dar a las implementaciones la libertad de entregar la señal al subproceso "más fácil posible" en caso de que haya diferencias en la facilidad de entrega entre diferentes subprocesos.
Del signal(7)
manual en un sistema Linux:
Se puede generar una señal (y por lo tanto pendiente) para un proceso en su totalidad (por ejemplo, cuando se envía usando kill(2)
) o para un subproceso específico (por ejemplo, ciertas señales, como SIGSEGV y SIGFPE, generadas como consecuencia de la ejecución de una instrucción específica en lenguaje de máquina están dirigidas a subprocesos, como señales dirigidas a un subproceso específico usando pthread_kill(3)
). Se puede enviar una señal dirigida al proceso a cualquiera de los subprocesos que actualmente no tenga bloqueada la señal. Si más de uno de los subprocesos tiene la señal desbloqueada, el kernel elige un subproceso arbitrario al que enviar la señal.
Y en pthreads(7)
:
Los subprocesos tienen distintas configuraciones de pila de señales alternativas. Sin embargo, la configuración de la pila de señales alternativas de un subproceso nuevo se copia del subproceso que lo creó, de modo que los subprocesos comparten inicialmente una pila de señales alternativa (corregido en el kernel 2.6.16).
Desde el pthreads(3)
manual en un sistema OpenBSD (como ejemplo de un enfoque alternativo):
Los manejadores de señales normalmente se ejecutan en la pila del subproceso que se está ejecutando actualmente.
(Actualmente no estoy al tanto de cómo se maneja esto cuando varios subprocesos se ejecutan simultáneamente en una máquina con varios procesadores)
La implementación anterior de LinuxThread de subprocesos POSIX solo permitía que las señales apuntaran a distintos subprocesos únicos. Desde pthreads(7)
en un sistema Linux:
LinuxThreads no admite la noción de señales dirigidas al proceso:las señales pueden enviarse solo a subprocesos específicos.
Extendiendo la respuesta aceptada, hay una vista más práctica, lo que encontré aquí.
La esencia es la siguiente:
Los controladores de señal son por proceso, pero las máscaras de señal son por subproceso.
- Por lo tanto, si instalamos/desinstalamos un controlador de señales (con signal() o sigaction()) en cualquier subproceso, afectará a todos ellos.
- Si un proceso recibe una señal, el controlador se ejecutará solo en un único subproceso. Este hilo se selecciona pseudoaleatoriamente entre ellos, cuya máscara de señal lo acepta. Mis experimentos muestran que siempre es el hilo con menos pid.
- Las señales enviadas a cualquier subproceso se consideran señales enviadas al proceso principal. Por lo tanto, si un subproceso recibe una señal, es muy posible que otro subproceso ejecute el controlador. Mejor si vemos que como si hilos (identificados por
tid
s, ids de subprocesos) se considerarían procesos enmascarados (identificados porpid
s) y señales enviadas a untid
se reenviaría a supid
. - Para la ejecución de un controlador de señal, en su máscara de señal, el número de señal dado se enmascara automáticamente. Esto es para evitar la ejecución del controlador de señales apiladas en una ráfaga de señales. Esto se puede cambiar con el
SA_NODEFER
bandera delsigaction(...)
llamar. - (3) y (4) dan como resultado que, en el caso de una ráfaga de señal, el sistema distribuye los controladores de señal posiblemente de forma más paralela.
- Sin embargo, si hemos configurado la sigaction con
SA_NODEFER
, siempre el mismo hilo recibirá la señal y se apilarán .