我正在一个具有事件处理循环的库中编写一个类:
class EventSystem(object):
def __init__(self):
self.queue = Queue.Queue()
self.thread = threading.Thread(target=self_process_loop)
self.thread.daemon = True
self.thread.start()
def _process_loop(self):
while True:
event = self.queue.get()
self._handle_event(event)
def _handle_event(self, event):
...
我已经将线程设置为daemon
线程,因此它与主程序一起退出,但这意味着它可能会在处理中被杀死。我真的想等待当前的处理迭代在它被杀死之前完成。
通常情况下,在这些情况下,会在while循环中检查一个标志,而某些方法 - stop()
,例如 - 将其设置为False
。如果可能的话,我宁愿避免这个要求。
以下是不是很糟糕?
def _process_loop(self):
while True:
event = self.queue.get()
self.thread.daemon = False
self._handle_event(event)
self.thread.daemon = True
修改:是的,这很糟糕:RuntimeError: cannot set daemon status of active thread
实现这一目标的正确方法是什么?
答案 0 :(得分:1)
您的想法是正确的(请参阅this documentation中的说明)使用标记,但不能使用内部daemon
属性作为标记,因为它将返回错误。
守护程序
一个布尔值,指示此线程是否为守护程序线程(True)或不是(False)。必须在调用start()之前设置它,否则引发RuntimeError。它的初始值继承自创建线程;主线程不是守护程序线程,因此在主线程中创建的所有线程都默认为daemon = False。
所以你应该创建另一个变量作为标志。
答案 1 :(得分:1)
使用控制生命周期的条件变量
捕获“杀死”守护进程的信号
每当信号发生时,设置终止条件,因此守护进程在处理完所有事件后退出
答案 2 :(得分:0)
继续umläute的回答(孩子从父线程接收信息的想法),我意识到我可以监视父线程的状态。
使线程非守护进程消除了退出中间处理的问题。然后检查父线程以查看它是否仍在运行我可以干净地退出:
class EventSystem(object):
def __init__(self):
self.queue = Queue.Queue()
self.parent_thread = threading.current_thread() # <-- Added
self.thread = threading.Thread(target=self_process_loop)
self.thread.start()
def _process_loop(self):
while self.parent_thread.is_alive(): # <-- Changed
try:
event = self.queue.get(timeout=1) # <-- Timeout added
except Queue.Empty:
continue
else:
self._handle_event(event)
def _handle_event(self, event):
...
这引入了轮询,但这是一个可行的解决方案,不需要客户端加入或停止后台线程。