检查Python多处理中的空队列
我有一个使用 python 包多处理和队列的程序。我的函数之一具有这种结构:
from multiprocessing import Process, Queue
def foo(queue):
while True:
try:
a = queue.get(block = False)
doAndPrintStuff(a)
except:
print "the end"
break
if __name__ == "__main__"
nthreads = 4
queue = Queue.Queue()
# put stuff in the queue here
for stuff in moreStuff:
queue.put(stuff)
procs = [Process(target = foo, args = (queue,)) for i in xrange(nthreads)]
for p in procs:
p.start()
for p in procs:
p.join()
其想法是,当我尝试从队列中提取数据并且队列为空时,它将引发异常并终止循环。所以我有两个问题:
1)这是一个安全的习语吗?有更好的方法来做到这一点吗?
2)我试图找出当我尝试从空队列中调用 .get()
时引发的确切异常是什么。目前我的程序正在捕获所有异常,当错误在其他地方并且我只收到“结束”消息时,这很糟糕。
我尝试过:
import Queue
queue = Queue.Queue()
[queue.put(x) for x in xrange(10)]
try:
print queue.get(block = False)
except Queue.Empty:
print "end"
break
但我收到了错误,就好像我没有捕获异常一样。捕获的正确异常是什么?
I have a program using python's packages multiprocessing and Queue. One of my functions have this structure:
from multiprocessing import Process, Queue
def foo(queue):
while True:
try:
a = queue.get(block = False)
doAndPrintStuff(a)
except:
print "the end"
break
if __name__ == "__main__"
nthreads = 4
queue = Queue.Queue()
# put stuff in the queue here
for stuff in moreStuff:
queue.put(stuff)
procs = [Process(target = foo, args = (queue,)) for i in xrange(nthreads)]
for p in procs:
p.start()
for p in procs:
p.join()
the idea is that when I try to extract from the queue and it is empty, it'll raise an exception and terminate the loop. So I have two questions:
1) is this a safe idiom? Are there better ways to do this?
2) I tried to find what is the exact exception that is raised when I try to .get()
from an empty queue. Currently my program is catching all exceptions, which sucks when the error is somewhere else and I only get a "the end" message.
I tried:
import Queue
queue = Queue.Queue()
[queue.put(x) for x in xrange(10)]
try:
print queue.get(block = False)
except Queue.Empty:
print "end"
break
but I got the error as if I hadn't caught the exception. What's the correct exception to catch?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
例外应该是
Queue.Empty
。但您确定您遇到了同样的错误吗?在第二个示例中,您还将队列本身从multiprocessing.Queue
切换到Queue.Queue
,我认为这可能是问题所在。这可能看起来很奇怪,但您必须使用
multiprocessing.Queue
类,但使用Queue.Empty
异常(您必须从Queue 中自行导入该异常)
模块)The exception should be
Queue.Empty
. But are you sure you got the same error? In your second example, you also switched the queue itself frommultiprocessing.Queue
toQueue.Queue
, which I think may be the problem.It might seem strange, but you have to use the
multiprocessing.Queue
class, but use theQueue.Empty
exception (which you have to import yourself from theQueue
module)在刷新放置缓冲区之前,队列似乎是空的,这可能需要一段时间。
我们问题的解决方案是使用 sentinels,或者可能是内置的 task_done() 调用:
It appears that the Queue is empty until the put buffers are flushed, which may take a while.
The solution to our problem is to use sentinels, or maybe the built-in task_done() call:
这是一个例子-正如@Steven上面所说,您需要使用标准队列中的queue.Empty异常。文档中的注释(https://docs.python.org/3/library/multiprocessing .html):
基本示例:
Here's an example- As @Steven said above, you need to use the queue.Empty exception from the standard queue. The note from documentation (https://docs.python.org/3/library/multiprocessing.html):
basic example:
尝试阅读 queue 库文档。您不是在寻找 Queue.empty() 吗?
Try reading the queue library docs. Aren't you looking for Queue.empty()?