Я немного отладил в KVM и обнаружил, что ядро - это , доставляющее сигналы на pid 1, когда обработчики сигналов установлены стандартным сигнальным модулем. Однако при получении сигнала «что-то» вызывает клон процесса, а не выводит ожидаемый результат.
Вот вывод strace, когда я отправляю HUP в нерабочий init.sig-mod:
![strace output](https://i.stack.imgur.com/n0ljT.png)
В результате запускается новый процесс (pid 23), который является клоном init.sig-mod:
![clone of init as pid 23](https://i.stack.imgur.com/O8Tpi.png)
У меня не было времени углубиться в причину, но это сужает вещи дальше. Возможно, это связано с логикой доставки сигналов Python (она регистрирует ловушку C, которая вызывает вашу функцию байт-кода при вызове). Техника ctypes обходит это. Соответствующие исходные файлы Python: Python / pythonrun.c и Modules / signalmodule.c , на случай, если вы захотите взглянуть поближе.
Старая информация - Я не уверен, что это решит вашу проблему, но может приблизить вас. я
сравнил эти разные способы установки обработчиков сигналов:
- Установка обработчика через сигнальный модуль Python.
- Обработчики сигналов Upstart.
- Использование ctypes для непосредственного вызова системного вызова
signal()
.
- Несколько быстрых тестов на C.
И системный вызов, вызванный ctypes signal()
, и Upstart sigaction()
Системные вызовы устанавливают флаг SA_RESTART
, когда обработчик зарегистрирован. настройка
этот флаг указывает, что, когда сигнал получен, в то время как процесс
выполнение или блокировка внутри определенных системных вызовов (чтение, запись, ожидание,
nanosleep и т. д.), после завершения обработчика сигнала системный вызов должен быть
автоматически перезагружается. Приложение не будет знать об этом.
Когда сигнальный модуль Python регистрирует обработчик, он обнуляет SA_RESTART
пометить, позвонив siginterrupt(signum, 1)
. Это говорит системе "когда
системный вызов прерывается сигналом после завершения обработчика сигнала
установите errno на EINTR и вернитесь из системного вызова ". Это оставляет за разработчиком
обработайте это и решите, следует ли перезапустить системный вызов.
Вы можете установить флаг SA_RESTART, зарегистрировав свой сигнал следующим образом:
import signal
signal.signal(signal.SIGHUP, handler)
signal.siginterrupt(signal.SIGHUP, False)