我有一個線程化的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