Ben*_*ack 16 python events multithreading signals daemon
我有一个线程化的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"
Run Code Online (Sandbox Code Playgroud)
但这导致没有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"
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:
threading.Event在某种程度上滥用了吗?threading.Event杀死信号处理程序?Dzi*_*inX 15
虽然就Python用户而言,Python信号处理程序是异步调用的,但它们只能出现在Python解释器的"原子"指令之间.这意味着在纯C中实现的长计算期间到达的信号(例如大文本上的正则表达式匹配)可能会延迟一段任意时间.
我测试了各种类threading和thread类,它们都没有按照你想要的方式工作 - 这可能是因为Python处理信号的方式.
在signal,然而,有一种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"
Run Code Online (Sandbox Code Playgroud)
我在Linux上检查过,它确实有效.如果您的应用程序不使用大量其他信号,我认为它不再归类为轮询和睡眠.