pthreads(7)
описує, що POSIX.1 вимагає всіх потоків в атрибутах спільного використання процесу, включаючи:
POSIX.1 також вимагає відзначити деякі атрибути для кожного потоку, включаючи:
У complete_signal
рутині ядра Linux є наступний блок коду - коментарі є досить корисними:
/*
* 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.
*/
Отже, ви бачите, що ви відповідаєте за те, куди подаються сигнали:
Якщо ваш процес встановив диспозицію сигналу до SIG_IGN
або SIG_DFL
, то сигнал ігнорується (або за замовчуванням - вбити, ядро чи ігнорувати) для всіх потоків.
Якщо ваш процес встановив розпорядження сигналу певним розпорядником обробника, то ви можете контролювати, який потік буде приймати сигнали, маніпулюючи конкретними масками сигналу потоку за допомогою pthread_sigmask(3)
. Ви можете призначити один потік для управління всіма ними, або створити один потік на сигнал, або будь-яку суміш цих параметрів для конкретних сигналів, або ви покладаєтесь на поточну поведінку ядра Linux за замовчуванням для доставки сигналу в основний потік.
Однак деякі сигнали є спеціальними відповідно до signal(7)
сторінки людини:
Сигнал може генеруватися (і, таким чином, очікувати) для процесу в цілому (наприклад, при надсиланні за допомогою kill (2) ) або для конкретної потоку (наприклад, певних сигналів, таких як SIGSEGV і SIGFPE, генерованих як наслідок виконання конкретна інструкція машинної мови спрямована на потоки, як і сигнали, спрямовані на певний потік, використовуючи
pthread_kill (3) ). Сигнал, орієнтований на процес, може бути доставлений до будь-якої з потоків, яка наразі не блокує сигнал. Якщо більше ніж один з потоків має сигнал розблокований, то ядро вибирає довільну нитку, до якої доставити сигнал.