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