Обработка двух последовательных SIGTERM - PullRequest
3 голосов
/ 03 августа 2011

Существует демон, который имеет два потока: th1, th2.th2 читает сокет, используя read(2).

Если я убиваю демона с помощью SIGTERM, th1 ловит и обрабатывает сигнал (устанавливает флаг завершения), после чего вызывается деструктор демона, он вызывает pthread_kill(th2, SIGTERM).Однако второй поток не получает SIGTERM, поэтому он не уничтожается (когда сокет получает данные и выходит из read(), он завершает выполнение, так как установлен флаг завершения).

Если я позвоню pthread_kill(th2, SIGUSR2), а затем pthread_kill(th2, SIGTERM), все закончится правильно.Таким образом, кажется, что UNIX не позволяет посылать идентичные сигналы последовательно.

Зависит ли это поведение от операционной системы?Можем ли мы гарантировать, что указанный поток получает SIGTERM из другого потока?

Ответы [ 2 ]

5 голосов
/ 03 августа 2011

Unix позволяет отправлять несколько последовательных сигналов процессу, хотя, если сигналы отправляются слишком близко друг к другу или дополнительный сигнал был отправлен в процесс до доставки уже ожидающего сигнала, то несколько сигналов могут быть объединены водиночное сигнальное событие.

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

Возможно, вы захотите также явно вызвать pthread_cancel(), поскольку read() является действительной точкой отмены.При необходимости вы можете добавить обработчик отмены, а также заблокировать состояние отмены потока, если вы используете функции, которые не безопасны для отмены.Вы можете прочитать некоторые советы по использованию pthread_cancel() здесь .

1 голос
/ 03 августа 2011

Относительно старой школы, но эффективный подход заключается в использовании select () и канала для повторной отправки сигналов всем потокам.(Вы выбираете () на своей ручке блокировки и ручке чтения канала).

...