Это на самом деле вызвало у меня замораживание мозга на несколько минут, и причина, по которой никогда не следует использовать signal()
в этот день и возраст, только усилилась во мне.
Прежде всего, из справочных страниц для signal()
Поведение сигнала () варьируется в зависимости от
Версии UNIX, а также отличается
исторически в разных версиях
Linux. Избегайте его использования: используйте
вместо sigaction (2).
и далее вниз:
- Если расположение установлено на функцию, то сначала либо
расположение сбрасывается до SIG_DFL, или
сигнал заблокирован (см. Портативность
ниже), а затем вызывается обработчик
с аргументом signum. Если вызов
обработчик вызвал сигнал
заблокирован, то сигнал разблокирован
по возвращении из обработчика.
В исходных системах Unix, когда был установлен обработчик, расположение было сброшено до SIG_DFL, не блокировал входящие сигналы типа того же , а затем запустил обработчик функция. Система V предоставила это, и ядро Linux делает то же самое.
Это означает, что после запуска кода в системе linux при вызове второго исключения он будет завершен напрямую.
Теперь самое интересное. BSD пытался улучшить это поведение. С man страниц снова:
На BSD, когда обработчик сигнала
вызывается, расположение сигнала не
сброс, и дальнейшие случаи
сигнал заблокирован от
доставлено, пока обработчик
выполнение.
И поскольку Mac OSX частично основан на BSD, после запуска кода на Mac OSX при вызове второго исключения будет в ожидании и ожидание выхода обработчика первого исключения. , Но так как вы никогда не выйдете, у вас тупик.
Вот почему вместо этого следует использовать sigaction()
, а не signal()
.
Теперь несколько советов:
Обработчики должны быть короткими и возвращаться быстро. Если вы выполняете вычисления и вызываете другие функции, вы, вероятно, делаете что-то не так. Сигналы не заменяют управляемую событиями структуру.
Вызывать функции, которые не являются асинхронными, плохо. Подумайте, что произойдет, если во время вызова к fprintf
произойдет исключение, а внутри обработчика будет вызван fprintf
. И обработчики сигналов, и данные программ могут быть повреждены, поскольку они работают с самим потоком.
Еще немного прочтения: «Делай» и «Не» внутри обработчика сигнала