pthreads(7)
descrive che POSIX.1 richiede tutti i thread in attributi di condivisione del processo, inclusi:
POSIX.1 richiede anche che alcuni attributi siano distinti per ogni thread, tra cui:
La complete_signal
routine del kernel Linux ha il seguente blocco di codice: i commenti sono piuttosto utili:
/*
* 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.
*/
Quindi, vedi che sei responsabile di dove vengono consegnati i segnali:
Se il processo ha impostato la disposizione di un segnale su SIG_IGN
o SIG_DFL
, il segnale viene ignorato (o predefinito: kill, core o ignore) per tutti i thread.
Se il processo ha impostato la disposizione di un segnale su una routine di gestione specifica, è possibile controllare quale thread riceverà i segnali manipolando maschere di segnali di thread specifiche utilizzando pthread_sigmask(3)
. È possibile nominare un thread per gestirli tutti, o creare un thread per segnale, o qualsiasi combinazione di queste opzioni per segnali specifici, oppure fare affidamento sull'attuale comportamento predefinito del kernel Linux di fornire il segnale al thread principale.
Alcuni segnali, tuttavia, sono speciali secondo la signal(7)
pagina man:
Un segnale può essere generato (e quindi in sospeso) per un processo nel suo complesso (ad esempio, quando viene inviato utilizzando kill (2) ) o per un thread specifico (ad esempio, alcuni segnali, come SIGSEGV e SIGFPE, generati come conseguenza dell'esecuzione una specifica istruzione in linguaggio macchina è diretta ai thread, così come i segnali mirati a un thread specifico utilizzando
pthread_kill (3) ). Un segnale diretto al processo può essere consegnato a uno qualsiasi dei thread che attualmente non ha il segnale bloccato. Se più di uno dei thread ha il segnale sbloccato, il kernel sceglie un thread arbitrario a cui inviare il segnale.