如何在调用task_done之前将项目放入JoinableQueue?

时间:2014-04-11 13:27:56

标签: python gevent python-multithreading

我创建了一个JoinableQueue实例并向其添加了一些项目。然后创建消费者工作者以在队列中使用这些项目。

但是问题是我需要能够在这些worker中向队列中添加新项目但是在q.get()之后没有调用task_done()时Gevent不允许我进行此操作。如果我在调用task_done()后将newItems添加到队列中,我就无法确定所有项目都被消耗了。

抛出gevent.hub.LoopExit: This operation would block forever

q = JoinableQueue()

def worker():
    item = q.get()
    newItems = consumeItem(item)
    [q.put(newItem) for newItem in newItems]
    q.task_done()

for item in initialItems:
    q.put(item)

for i in range(10):
    gevent.spawn(worker)

q.join() # I have to be sure all items are consumed when join stops blocking the program.

如何解决此问题?

1 个答案:

答案 0 :(得分:0)

您的员工只运行一次。如果你的队列中的项目多于你的衍生工人,那么它永远不会完成。

解决方案很简单,只需向工人添加一个循环:

def worker():
    for item in iter(q.get, None):
        newItems = consumeItem(item)
        [q.put(newItem) for newItem in newItems]
        q.task_done()

现在所有人都继续工作,直到队列为空。