如何让等待队列的线程退出?

12 投票
4 回答
7184 浏览
提问于 2025-04-16 17:33

我在应用程序里有两个线程。一个线程负责往一个叫做Queue的地方放值,另一个线程则从这个Queue里取值并处理它们。

现在我在关闭应用程序的时候遇到了一个问题。处理Queue里项目的那个线程卡住了,停在了:

item = request_queue.get() # this call blocks until an item is available

这个线程只有在Queue里再添加一个项目的时候才能结束,但因为主线程在关闭应用程序,所以它不会再添加任何东西,这样就导致应用程序锁死了。

那么...我该怎么做才能让Queue.get()Queue里没有东西的时候也能返回呢?

4 个回答

0

这个问题在主线程中调用 Queue.get() 时仍然可能发生,所以设置 setDaemon(True) 并不是一个通用的解决办法。

比如说,这段脚本是无法通过 Ctrl-C 停止的。

#!/usr/bin/python
import Queue

theQ = Queue.Queue()
print "one thread getting from Queue"
print theQ.get()

与其在 Queue.get() 上设置超时并处理异常,不如简单地使用一个等待循环,直到有东西可以处理。这样,这段脚本就可以通过 Ctrl-C 被终止了。

#!/usr/bin/python
import Queue
theQ = Queue.Queue()
print "one thread getting from Queue"
while theQ.empty():
    time.sleep(0.01) # or whatever value is appropriate for your event arrivals
print theQ.get()
1

因为这个阻塞的线程不是主线程,所以你也可以设置 .daemon = True

import time
import threading
from Queue import Queue

def getter(q):
    while True:
        print 'getting...'
        print q.get(), 'gotten'

def putter(q):
    for i in range(10):
        time.sleep(0.5)
        q.put(i)
        time.sleep(0.5)

q = Queue()
get_thread = threading.Thread(target=getter, args=(q,))
get_thread.daemon = True
get_thread.start()

putter(q)
19

其实答案很简单。选择一个对于处理这个Queue的代码来说无效的值(None是最合适的),然后把这个值放入Queue中。接着,当处理Queue的线程收到这个值时,就让它退出。

while True:

    item = request_queue.get()

    if item is None:
        break

    # process the Queue as per normal...

撰写回答