我有一个线程化的Python守护进程。像任何好的守护进程一样,它想要启动它的所有工作线程,然后等待,直到告知终止。终止的正常信号是SIGTERM
,并且在大多数语言中,我会坚持通过等待事件或互斥体来终止,因此使用threading.Event
对我而言意义重大。问题在于Python的Event
对象和Unix信号看起来并没有很好地一起玩。为什么使用threading.Event导致SIGTERM不被捕获?
可正常工作,终止于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
在某些方面? - 如果我不是,除了第一个例子中的poll-and-sleep机制,还有其他的选择吗?
- 另外,如果我不是,为什么使用
threading.Event
杀死信号处理程序?
Python的烦人的功能,但完美的解决方案。谢谢。我承认我没有想到在'signal'的使用上寻找额外的限制,因为我知道等价的C将会正常工作。 – 2010-06-23 17:14:17
这是否意味着处理信号的唯一方法是专用主线程(父)捕获信号(通过阻塞'signal.pause()')?这意味着主线程不能再做任何有用的事情。换句话说,你不可能有一个主/辅模型(2个线程相互对话),但你需要一个主/辅助+工作者模型(2个工作人员彼此交谈,主人不做任何事情。 – 2013-01-16 22:42:00