2013-11-26 2 views
8

Классический способ указать обработчик для определенного сигнала через sigaction. Linux дополнительно предоставляет функциональность signalfd, где мы можем подключать сигналы к файловому дескриптору, а затем применять select/(e) опрос к этому дескриптору, который идеально подходит для концепции многих систем, управляемых циклом событий.Может ли быть гонка между signalfd и sigaction?

Мне интересно, что произойдет/произойдет, когда оба механизма столкнутся. Могут ли быть условия гонки? На signalfd страницы руководства (http://man7.org/linux/man-pages/man2/signalfd.2.html) мы читаем:

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

Итак, в нем говорится: «Обычно» мы используем маску сигнала, чтобы предотвратить обработку обработчиком (по умолчанию) обработчика. Он не говорит, что мы должны блокировать этот сигнал, когда у нас есть файловый дескриптор, подключенный к нему. К сожалению, на странице руководства не указано, что происходит, когда мы не блокируем сигнал.

Это похоже на плохо определенное поведение. Я не считаю, что это на самом деле не определено, и мне интересно, знает ли кто-нибудь здесь i), я могу найти подробную информацию о том, как должна себя вести система или ii), как она себя ведет.

Что я конкретно интересует, этот порядок исполнения:

  1. signalfd для определенного сигнала, в том числе закупорка этого сигнала
  2. unblockage этого сигнала
  3. sigaction для этого сигнала (по умолчанию обработчик или пользовательский обработчик)

Это неопределенное поведение или есть стандарт/спецификация того, что должно произойти? Всегда ли обработчик всегда имеет приоритет над файловым дескриптором? Является ли обработчик вызванным и, дескриптор файла запускает событие? Устанавливает ли настройка sigaction маску сигнала, шаг рендеринга (2) не нужен?

Я мог бы попытаться получить фактическое поведение от систематических тестов, связанных с фактическим кодом. Тем не менее, я, конечно, предпочитаю найти подробную документацию и считаю, что я не смог найти правильную ссылку самостоятельно.

+0

Это, похоже, сводится к вопросу о том, оправдано ли использование * обычно * в приведенном выше описании. Игнорирование проблемы в том, что нет ничего * прекращения * любого, кто не блокирует первые сигналы, действительно ли используется префикс * не * блокировки сигналов перед использованием 'signalfd' или' sigwaitinfo'? Мне кажется, что все эти призывы состоят в том, чтобы воздействовать на * ожидающие * сигналы, чтобы обойти их варианты доставки. Поэтому я опишу его: кто-нибудь знает, где разблокированные сигналы и любой из этих вызовов имеет смысл? – Duck

ответ

11

signalfd ведет себя идентично sigwaitinfo, за исключением того, что вы получаете доступ к информации через дескриптор файла. Это означает, что signalfd принимает сигналы синхронно, а обработчики сигналов (или в зависимости от того, что выбрано по умолчанию) называются сначала.

TLPI главы 22.10 и 22.11 (M. Kerrisk).

Поведение четко определено, но не обязательно, что можно было бы ожидать, а manpage сформулировано довольно плохо. Высказывание "обычно ...должен « предполагает, что вам или нет, или что еще хуже, что автор не совсем уверен.
Если вы хотите, чтобы он работал« правильно », то есть так, как вы обычно ожидали (см., я использовал «обычно» тоже), вам нужно блокировать сигналы. В противном случае сигнал будет доступен через дескриптор файла, но обработчик все равно будет вызван первым (что вполне законно, но большинство людей, вероятно, рассмотрят это «странное поведение» ").

Таким образом, существуют два разных условия гонки. Одно условие - это то, о чем вы спрашиваете, но хотя поведение немного неожиданно, оно четко определено и (вид) задокументировано, и если вы думаете об этом, то это не строго условие гонки. Скорее это своего рода «двойная доставка».
T другое состояние гонки - это возможность получения сигнала после того, как вы создали signalfd, но перед тем, как заблокировать сигнал. Это очень маловероятно, но в принципе это может произойти. К счастью, решение легко, вы можете заблокировать сигнал сначала, а затем создать дескриптор файла (который затем будет немедленно готов, если сигнал достигнет промежутка времени).

Последовательность команд, которые вы назвали (создайте дескриптор файла, разблокируйте, затем sigaction), имеет аналогичное состояние гонки. Сначала вы должны установить обработчик, а затем разблокировать или передать сигнал до того, как будет обработчик. Но это независимо от signalfd. Дескриптор файла все равно можно было бы использовать для считывания сигнала в любом случае, но назначение по умолчанию могло бы убить процесс, если сигнал достигнет разблокировки и установки обработчика.

+1

Очень полезный ответ, поэтому я люблю StackOverflow. Благодарю. –

Смежные вопросы