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

发布于 2024-11-07 10:55:54 字数 472 浏览 0 评论 0原文

我的应用程序中有两个线程。一个将值放入 Queue 中,另一个则拉取将它们从队列中取出并进行处理。

关闭应用程序时我面临着两难的境地。处理 Queue 中项目的线程被卡住:

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

唯一终止线程的事情是如果另一个项目被添加到 Queue 中 - 并且因为主线程不这样做不添加任何内容(因为它正在关闭),应用程序将锁定。

那么...即使 Queue 上没有任何内容,我如何指示 Queue.get() 以某种方式返回?

I've got two threads in my application. One that puts values in a Queue, and another that pulls them from the Queue and processes them.

I am faced with a dilemma when shutting the application down. The thread that processes items in the Queue is stuck on:

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

The only thing that will terminate the thread is if another item is added to the Queue - and since the main thread doesn't add anything (because it's shutting down), the application locks.

So... how can I instruct Queue.get() to somehow return even if there is nothing on the Queue?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

愁杀 2024-11-14 10:55:54

事实证明答案非常简单。选择一个对于处理Queue 的代码无效的值(None 是理想的选择)并将其推入Queue。然后让 Queue 处理线程在获取值时退出:

while True:

    item = request_queue.get()

    if item is None:
        break

    # process the Queue as per normal...

The answer it turns out is quite simple. Pick a value that would be invalid for the code that processes the Queue (None is ideal for that) and push that into the Queue. Then have the Queue processing thread quit when it gets the value:

while True:

    item = request_queue.get()

    if item is None:
        break

    # process the Queue as per normal...
蓦然回首 2024-11-14 10:55:54

由于阻塞线程不是主线程,您还可以设置.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)

Since the blocking thread is not the main thread, you could also set .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)
柒七 2024-11-14 10:55:54

如果在主线程中调用 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()

This problem can still occur if Queue.get() is called in the main thread - so the setDaemon(True) answer is not a universal solution.

For example this script cannot be stopped with Ctrl-C

#!/usr/bin/python
import Queue

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

Rather than putting a timeout on Queue.get() and dealing with exceptions, a simple solution is to do a wait loop until something is there. This script can be killed with 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()
凉薄对峙 2024-11-14 10:55:54

您可以检查队列大小并在退出队列之前等待特定时间,以便您知道退出时没有添加更多数据项。

last_obj_time = time.time()
while True:
    if request_queue.qsize() > 0:
        item = request_queue.get()
        last_obj_time = time.time()

    elif time.time() - last_obj_time > 10:
        break

You can check queue size and wait a specific time before exiting queue, so that you know more data items are not being added at the time of exiting.

last_obj_time = time.time()
while True:
    if request_queue.qsize() > 0:
        item = request_queue.get()
        last_obj_time = time.time()

    elif time.time() - last_obj_time > 10:
        break
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文