Я хотел бы точно знать, как выполнение асинхронных обработчиков сигналов работает в Linux. Во-первых, мне неясно , какой поток выполняет обработчик сигнала. Во-вторых, я хотел бы знать шаги, которые выполняются, чтобы заставить поток выполнить обработчик сигнала.
По первому вопросу я прочитал два разных, на первый взгляд, противоречивых объяснения:
Ядро Linux, Андриес Брауэр , §5.2 Состояния «Прием сигналов» :
Когда приходит сигнал, процесс прерывается, текущие регистры сохраняются, и вызывается обработчик сигнала. Когда обработчик сигнала возвращается, прерванная деятельность продолжается.
Вопрос StackOverflow «Работа с асинхронными сигналами в многопоточной программе» заставляет меня думать, что поведение Linux похоже на поведение SCO Unix ]:
Когда сигнал доставляется процессу, если он перехватывается, он будет обработан одним и только одним из потоков, удовлетворяющих любому из следующих условий:
Поток заблокирован в sigwait (2) системный вызов, аргумент которого включает тип перехваченного сигнала.
Поток, маска сигнала не включает тип перехваченного сигнала.
Дополнительные соображения:
- Поток, заблокированный в sigwait (2) , получает предпочтение перед потоком, не блокирующим тип сигнала.
- Если более одного поток соответствует этим требованиям (возможно, два потока вызывают sigwait (2) ), тогда будет выбран один из них. Этот выбор не предсказуем прикладными программами.
- Если ни один поток не является подходящим, сигнал будет оставаться «ожидающим» на уровне процесса, пока какой-либо поток не станет подходящим.
Также, «Обработка сигналов Linux» Модель "Моше Бара гласит:" Асинхронные сигналы доставляются первому потоку, который не блокирует сигнал. ", Что я интерпретирую как означающее, что сигнал доставляется некоторому потоку, имеющему его сигмаску , но не , включая сигнал.
Какой из них правильный?
По второму вопросу, что происходит со стеком и содержимым регистра для выбранного потока? Предположим, что поток-для-выполнения-обработчик-сигнала T находится в процессе выполнения функции do_stuff ()
.Используется ли стек потока T непосредственно для выполнения обработчика сигнала (т.е. адрес трамплина сигнала помещается в стек T , а поток управления переходит к обработчику сигнала)? Как вариант, используется ли отдельный стек? Как это работает?