Linux man 2 signal
объясняет, что происходит, когда вы устанавливаете обработчик сигнала с помощью signal
. Есть две возможности:
- Расположение сигнала сбрасывается до
SIG_DFL
, и затем вызывается обработчик. Чтобы снова обработать этот сигнал, вам нужно переустановить sh обработчик сигнала. Это сработало бы так, как вы ожидали.
Или:
Сигнал блокируется, и затем вызывается обработчик. Когда обработчик возвращается, сигнал разблокируется. Если обработчик не возвращается, сигнал все еще блокируется, что и происходит с вами.
Так что один работает с вашим кодом, а другой - нет. Но какое из двух применимо? Нет надежного способа узнать. Posix допускает обе возможности, и обе возможности существуют на разных платформах. По этой причине справочная страница Linux рекомендует:
Единственное переносимое использование signal () - это установить расположение сигнала на SIG_DFL
или SIG_IGN
... [D] o не используйте его для [установки обработчика сигнала].
POSIX.1 решил проблему переносимости, указав sigaction(2)
, которая обеспечивает явный контроль семантики при вызове обработчика сигнала; используйте этот интерфейс вместо signal()
.
Это хороший совет. Когда вы перейдете на использование sigaction
, вы, вероятно, захотите go для первого варианта выше, который требует:
sa.sa_flags = SA_RESETHAND | SA_NODEFER
Это также происходит из справочной страницы Linux, что стоит читать полностью. (Конечно, справочная страница sigaction
еще более актуальна.)