Как асинхронные обработчики сигналов выполняются в Linux?

Я хотел бы точно знать, как выполнение асинхронных обработчиков сигналов работает в Linux. Во-первых, мне неясно , какой поток выполняет обработчик сигнала. Во-вторых, я хотел бы знать шаги, которые выполняются, чтобы заставить поток выполнить обработчик сигнала.

По первому вопросу я прочитал два разных, на первый взгляд, противоречивых объяснения:

  1. Ядро Linux, Андриес Брауэр , §5.2 Состояния «Прием сигналов» :

    Когда приходит сигнал, процесс прерывается, текущие регистры сохраняются, и вызывается обработчик сигнала. Когда обработчик сигнала возвращается, прерванная деятельность продолжается.

  2. Вопрос StackOverflow «Работа с асинхронными сигналами в многопоточной программе» заставляет меня думать, что поведение Linux похоже на поведение SCO Unix ]:

    Когда сигнал доставляется процессу, если он перехватывается, он будет обработан одним и только одним из потоков, удовлетворяющих любому из следующих условий:

    1. Поток заблокирован в sigwait (2) системный вызов, аргумент которого включает тип перехваченного сигнала.

    2. Поток, маска сигнала не включает тип перехваченного сигнала.

    Дополнительные соображения:

    • Поток, заблокированный в sigwait (2) , получает предпочтение перед потоком, не блокирующим тип сигнала.
    • Если более одного поток соответствует этим требованиям (возможно, два потока вызывают sigwait (2) ), тогда будет выбран один из них. Этот выбор не предсказуем прикладными программами.
    • Если ни один поток не является подходящим, сигнал будет оставаться «ожидающим» на уровне процесса, пока какой-либо поток не станет подходящим.

    Также, «Обработка сигналов Linux» Модель "Моше Бара гласит:" Асинхронные сигналы доставляются первому потоку, который не блокирует сигнал. ", Что я интерпретирую как означающее, что сигнал доставляется некоторому потоку, имеющему его сигмаску , но не , включая сигнал.

Какой из них правильный?

По второму вопросу, что происходит со стеком и содержимым регистра для выбранного потока? Предположим, что поток-для-выполнения-обработчик-сигнала T находится в процессе выполнения функции do_stuff () .Используется ли стек потока T непосредственно для выполнения обработчика сигнала (т.е. адрес трамплина сигнала помещается в стек T , а поток управления переходит к обработчику сигнала)? Как вариант, используется ли отдельный стек? Как это работает?

51
задан Community 23 May 2017 в 00:31
поделиться