Убийство будет прервано сигналом?

Например, если я использую kill (функцию в сигнале библиотеки C) для отправки сигнала SIGINT дочернему элементу, будет ли сигнал SIGCHLD от дочернего элемента перехвачен до возврата из функции kill?


person Rossil    schedule 03.05.2020    source источник


Ответы (3)


Хотя системный вызов kill нельзя прервать (по крайней мере, согласно справочной странице), есть по крайней мере два случая, когда обработчик SIGCHLD может быть запущен до возврата функции:

  1. Если в вашем процессе есть еще один поток, ядро ​​может выбрать запуск обработчика сигнала еще до того, как системный вызов kill вернется в ваш первый поток.
  2. Вероятно, вы используете функцию-оболочку для kill из вашей библиотеки libc. Обработчик сигнала может работать между возвратом системного вызова к нему и возвратом к вашему коду.

Поэтому, если вы хотите убедиться, что вы не получите SIGCHLD до тех пор, пока не вернется kill, вам нужно использовать sigprocmask, чтобы заблокировать его до kill, пока вы не будете к этому готовы.

person Joseph Sible-Reinstate Monica    schedule 03.05.2020
comment
Даже если вы вызываете kill напрямую с помощью встроенной инструкции asm (syscall или int или что-то еще, что использует ваша цель), обработчик сигнала может запуститься перед инструкцией после этого. Так что, хотя технически это происходит после возврата системного вызова, это бесполезно. - person Chris Dodd; 03.05.2020
comment
@ChrisDodd Технически правильный - лучший вид правильного :) Но если серьезно, решение (расплывчатой) проблемы OP по-прежнему блокирует ее с помощью sigprocmask, пока вы не будете готовы к этому. - person Joseph Sible-Reinstate Monica; 03.05.2020
comment
Спасибо за вашу помощь. Когда я говорю о прерывании, я имею в виду именно сигнал SIGCHLD, испускаемый потомком, который завершается функцией kill. Я пренебрегаю тем, что kill — это системный вызов, поэтому все сигналы будут заблокированы до того, как программа вернется в пользовательский режим. Но меня все еще смущает комментарий Криса Додда. Могу ли я сказать, что до того, как функция kill вернется, она должна вернуться из режима ядра в пользовательский режим, и период, когда она остается в пользовательском режиме перед возвратом, - это время, когда она будет прервана сигналом? - person Rossil; 06.05.2020
comment
@Rossil Поток вашего процесса, выдавший kill, не будет прерван сигналом, пока он все еще находится в режиме ядра. - person Joseph Sible-Reinstate Monica; 06.05.2020

Обработка сигналов является асинхронной. Поэтому в любом случае нет никакой гарантии, что SIGCHLD, испущенный при завершении дочернего процесса, будет получен родителем до возврата вызова kill. Я предполагаю, что kill обычно выигрывает гонку и возвращается до прибытия SIGCHLD, но полагаться на это небезопасно.

person John Bollinger    schedule 03.05.2020

Я не знаю, отвечает ли это на ваш вопрос, но, читая справочную страницу Linux, возможные возвращаемые значения kill: EINVAL, EPERM и ESRCH. EINTR не один из них. Это заставляет меня думать, что функция не будет прервана. По крайней мере, системный вызов не будет прерван.

РЕДАКТИРОВАТЬ: я имею в виду errno, а не возврат, значения.

person Daniel Walker    schedule 03.05.2020