成功挂起后退出
import threading
import Queue as queue
import time
import sys
class WorkItem(threading.Thread):
def __init__(self):
self.P1 = 20
self.P2 = 40
threading.Thread.__init__(self)
def run(self):
print "P1 = %d" % (self.P1)
print "P2 = %d" % (self.P2)
class WorkQueue(object):
def __init__(self,queueLimit = 5):
self.WorkQueue = queue.Queue(queueLimit)
self.dispatcherThread = threading.Thread(target=self.DequeueWorker)
self.dispatcherThread.start()
self.QueueStopEvent = threading.Event()
self.QueueStopEvent.clear()
def DequeueWorker(self):
print "DequeueWorker Enter .."
while not self.QueueStopEvent.isSet():
workItem = self.WorkQueue.get(True)
workItem.start()
def DispatchToQueue(self,workItem):
self.WorkQueue.put(workItem,True)
def Stop(self):
self.QueueStopEvent.set()
self.queue = None
def main():
q = WorkQueue()
for i in range(1,20):
t = WorkItem()
q.DispatchToQueue(t)
time.sleep(10)
q.Stop()
if __name__ == "__main__":
main()
我可以看到DequeueWorker是一个仍在运行和待定的人,并试图理解为什么因为我确实发出Stop事件的信号。我期待循环会退出。
>>> $w
=> Frame id=0, function=DequeueWorker
Frame id=1, function=run
Frame id=2, function=__bootstrap_inner
Frame id=3, function=__bootstrap
帮助赞赏!!
答案 0 :(得分:1)
您在get
设置为block
时调用True
,这意味着它将阻塞,直到某个项目在队列中实际可用。在您的代码中,一旦工作队列耗尽,下一个get
将无限期地阻塞,因为它正在等待永远不会发生的额外工作项(并且不会让while
循环的下一次迭代执行,因此QueueStopEvent
的状态不再被检查。尝试将DequeueWorker
方法修改为:
def DequeueWorker(self):
print "DequeueWorker Enter .."
while not self.QueueStopEvent.isSet():
try:
workItem = self.WorkQueue.get(True, timeout=3)
workItem.start()
except queue.Empty: continue
现在,当工作队列耗尽后调用get
时,它将超时(在这种情况下3秒后,我随意选择)并引发queue.Empty
异常。在这种情况下,我们只是让循环继续到下一次迭代,当QueueStopEvent
最终被设置时,循环将自行中断。
其他选项是在get
设置为block
的情况下调用False
,或在get_nowait
/ try
内使用except
方法块:
workItem = self.WorkQueue.get(False)
workItem = self.WorkQueue.get_nowait()
虽然当队列为空时会产生非常紧张的while
循环。