Моя первая мысль - неправильная обработка сигналов, но в вашем сообщении недостаточно информации для написания тестового кода, который бы повторял вашу ошибку.Но я могу дать вам несколько мест, чтобы посмотреть.Прошу прощения, если я расскажу о некоторых основах сигналов, которые вы уже знаете для будущих читателей.
Прежде всего, я не знаю, используете ли вы устаревшие функции signal () или новые процедуры POSIX sigaction ()ловить сигналы.sigset () полезен между GNU.
Legacy Signals - signal ()
Почти невозможно, если вообще невозможно, гарантировать герметичностьпроцессор сигналов, использующий оригинальный процессор сигналов во всех средах.
- В некоторых системах UNIX входящий обработчик сигнала может сбросить обработчик до состояния по умолчанию.Последующие сигналы гарантированно будут потеряны, если только обработчик явно не сбросит сигнал.
- обработчики signal () не должны предполагать, что их вызывают один раз для каждого сигнала.
- Обработчики должны выполнять цикл
while( ( pid = waitpid( -1, &signal, WNOHANG ) ) > 0 )
, пока не будет найдено больше сигналов, поскольку устаревшие сигналы не устанавливаютсостояние bool, указывающее хотя бы один сигнал, является выдающимся.Фактический счет неизвестен. - Обработчики должны допускать отсутствие сигналов, если предыдущий цикл while () обработал сигнал.
- Разрешить сигналы от неизвестных процессов ... если программа, которую вы запускаете, также запускает процесс внука, вы можете унаследовать этот процесс, если ваш ребенок быстро завершит работу.
Советуйте, держите нос и бегите от устаревших сигналов.
Отсутствие цикла while () в унаследованном обработчике и нескольких SIGCHILD, одного из вашего sudo и одного или нескольких из неожиданных уволенных внуковот судо.Если при поступлении сигнала внука обрабатывается только один SIGCHILD, ожидаемый сигнал программы не будет перехвачен.
POSIX Signals - sigaction ()
POSIX сигналыможет убрать все сбои устаревших сигналов.
- Установить обработчик без восстановления (восстановление НЕ является частью сигналов POSIX и часто, по моему мнению, является злом, когда вы можете получитьболее одного сигнала для обработки таким же образом).
- sigaction () сигналы липкие ... они живут до тех пор, пока явно не изменятся (замечательно!).Ни одно из этих трудоемких требований повторной установки обработчика сигнала в обработчике.
- Установить маску для маскировки текущего сигнала при обработке сигнала.Параноики также будут маскировать любой другой сигнал, передаваемый тому же обработчику.
Отсутствие маски может вызвать странные вещи, такие как потеря трека сигнала, если вы получаете SIGCHILD в обработчике SIGCHILD.
GNU - sigset()
GNU предоставляет полезный промежуточный элемент, который имеет те же сигнатуры вызова, что и signal (), но устраняет большинство проблем.Некоторые дополнительные функции управления также доступны.Использование sigset () легко решает многие проблемы с сигналом.
Напоминания
Думайте об обработчиках сигналов как о потоках в вашей программе, даже если вы не используете потоки в других отношенияхв коде.
В старые времена вам приходилось выполнять абсолютно минимальную обработку в обработчиках сигналов ... не вызывать библиотечный код, такой как printf, который имеет побочные эффекты.Я все еще придерживаюсь этого, когда приходится использовать устаревшие обработчики сигналов и всегда использовать многопоточные предостережения в новых обработчиках.