pthreads(7)
opisuje, że POSIX.1 wymaga wszystkich wątków w atrybutach udziału procesu, w tym:
POSIX.1 wymaga również, aby niektóre atrybuty były odrębne dla każdego wątku, w tym:
Procedura jądra Linuksa complete_signal
ma następujący blok kodu - komentarze są bardzo przydatne:
/*
* 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.
*/
Więc widać, że ty jesteś odpowiedzialny za gdzie sygnały są dostarczane:
Jeśli twój proces ustawił dyspozycję sygnału na SIG_IGN
lub SIG_DFL
, sygnał jest ignorowany (lub domyślnie - kill, core lub ignore) dla wszystkich wątków.
Jeśli twój proces ustawił dyspozycję sygnału na określoną procedurę obsługi, możesz kontrolować, który wątek otrzyma sygnały, manipulując określonymi maskami sygnału wątku za pomocą pthread_sigmask(3)
. Możesz wyznaczyć jeden wątek do zarządzania nimi wszystkimi lub utworzyć jeden wątek na sygnał lub dowolną mieszankę tych opcji dla określonych sygnałów, lub polegać na bieżącym domyślnym zachowaniu jądra Linuksa polegającym na dostarczaniu sygnału do głównego wątku.
Jednak niektóre sygnały są specjalne według strony podręcznika signal(7)
:
Sygnał może być generowany (a zatem oczekujący) dla procesu jako całości (np., Gdy jest wysyłany przy użyciu funkcji kill (2) ) lub dla określonego wątku (np. Pewne sygnały, takie jak SIGSEGV i SIGFPE, generowane w wyniku wykonania określone instrukcje języka maszynowego są skierowane do wątków, podobnie jak sygnały kierowane do określonego wątku za pomocą
pthread_kill (3) ). Sygnał skierowany na proces może być dostarczony do dowolnego z wątków, w których sygnał aktualnie nie jest zablokowany. Jeśli więcej niż jeden wątek ma odblokowany sygnał, to jądro wybiera dowolny wątek, do którego ma dostarczyć sygnał.