У меня есть потоковый демон Python. Как любой хороший демон, это хочет запустить все свои рабочие потоки, затем ожидать вокруг, пока этому не говорят завершиться. Нормальный сигнал для завершения SIGTERM
, и на большинстве языков я держал бы для завершения путем ожидания на событии или взаимном исключении, таким образом с помощью threading.Event
имевший смысл мне. Проблема состоит в том что Python Event
объект и сигналы Unix, кажется, не играют хорошо вместе.
Это работает как ожидалось, завершаясь на SIGTERM
:
import signal
import time
RUN = True
def handle(a, b):
global RUN
print "handled"
RUN = False
signal.signal(signal.SIGTERM, handle)
while RUN:
time.sleep(0.250)
print "Stopping"
но это приводит к нет SIGTERM
будучи поставленным (т.е. вполне кроме выхода, "обрабатываемого" никогда, не печатается):
import signal
import threading
RUN_EVENT = threading.Event()
def handle(a, b):
print "handled"
RUN_EVENT.set()
signal.signal(signal.SIGTERM, handle)
RUN_EVENT.wait()
print "Stopping"
Таким образом, мой вопрос:
threading.Event
в некотором роде?threading.Event
уничтожить обработчик сигналов?Из Документация Python по сигналам :
Хотя обработчики сигналов Python вызываются асинхронно с точки зрения пользователя Python, они могут возникать только между «атомарными» инструкциями интерпретатора Python. Это означает, что сигналы, поступающие во время длительных вычислений, реализованных исключительно на C (например, совпадение регулярных выражений в больших объемах текста), могут задерживаться на произвольное время.
Я тестировал различные классы threading
и thread
, и ни один из них не работает так, как вы этого хотите - вероятно, это связано с тем, как Python обрабатывает сигналы.
В сигнале
, однако, есть функция pause ()
, которая отключается до тех пор, пока процесс не получит сигнал. Ваш измененный пример будет выглядеть так:
import signal
RUN = True
def handle(a, b):
global RUN
print "handled"
RUN = False
signal.signal(signal.SIGTERM, handle)
while RUN:
signal.pause()
print "Stopping"
Я проверил его в Linux, он работает. Я не думаю, что он больше классифицируется как опрос и сон, если ваше приложение не использует много других сигналов.