pthreads(7)
describe que POSIX.1 requiere que todos los subprocesos en un proceso compartan atributos, incluidos:
- disposiciones de señales
POSIX.1 también requiere que algunos atributos sean distintos para cada hilo, incluyendo:
-
máscara de señal (
pthread_sigmask(3)
) -
pila de señal alternativa (
sigaltstack(2)
)
complete_signal
del kernel de Linux la rutina tiene el siguiente bloque de código; los comentarios son muy útiles:
/*
* 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.
*/
Entonces, ves que tú están a cargo de dónde se envían las señales:
Si su proceso ha establecido la disposición de una señal en SIG_IGN
o SIG_DFL
, luego la señal se ignora (o por defecto -- matar, core o ignorar) para todos los subprocesos.
Si su proceso ha establecido la disposición de una señal para una rutina de controlador específica, entonces puede controlar qué subproceso recibirá las señales mediante la manipulación de máscaras de señal de subproceso específicas usando pthread_sigmask(3)
. Puede designar un subproceso para administrarlos todos, o crear un subproceso por señal, o cualquier combinación de estas opciones para señales específicas, o confiar en el comportamiento predeterminado actual del kernel de Linux de enviar la señal al subproceso principal.
Algunas señales, sin embargo, son especiales según el signal(7)
página man:
Una señal puede ser generada (y por lo tanto pendiente) para un proceso como un todo (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 ejecutar un las instrucciones específicas en lenguaje de máquina están dirigidas a subprocesos, al igual que las señales dirigidas a un subproceso específico utilizando 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, entonces el kernel elige un subproceso arbitrario al que enviar la señal.
Esto está ligeramente matizado, según la versión del kernel de Linux que esté utilizando.
Asumiendo 2.6 subprocesos posix, y si está hablando de que el sistema operativo envía SIGTERM o SIGHUP, la señal se envía al proceso, que es recibido y manejado por el subproceso raíz. Usando subprocesos POSIX, también puede enviar SIGTERM a subprocesos individuales, pero sospecho que está preguntando qué sucede cuando el sistema operativo envía la señal al proceso.
En 2.6, SIGTERM hará que los subprocesos secundarios salgan "limpiamente", mientras que en 2.4, los subprocesos secundarios quedaron en un estado indeterminado.