我希望将multiprocessing.Queue
转储到列表中。为此,我编写了以下函数:
import Queue
def dump_queue(queue):
"""
Empties all pending items in a queue and returns them in a list.
"""
result = []
# START DEBUG CODE
initial_size = queue.qsize()
print("Queue has %s items initially." % initial_size)
# END DEBUG CODE
while True:
try:
thing = queue.get(block=False)
result.append(thing)
except Queue.Empty:
# START DEBUG CODE
current_size = queue.qsize()
total_size = current_size + len(result)
print("Dumping complete:")
if current_size == initial_size:
print("No items were added to the queue.")
else:
print("%s items were added to the queue." % \
(total_size - initial_size))
print("Extracted %s items from the queue, queue has %s items \
left" % (len(result), current_size))
# END DEBUG CODE
return result
但由于某种原因,它不起作用。
观察以下shell会话:
>>> import multiprocessing
>>> q = multiprocessing.Queue()
>>> for i in range(100):
... q.put([range(200) for j in range(100)])
...
>>> q.qsize()
100
>>> l=dump_queue(q)
Queue has 100 items initially.
Dumping complete:
0 items were added to the queue.
Extracted 1 items from the queue, queue has 99 items left
>>> l=dump_queue(q)
Queue has 99 items initially.
Dumping complete:
0 items were added to the queue.
Extracted 3 items from the queue, queue has 96 items left
>>> l=dump_queue(q)
Queue has 96 items initially.
Dumping complete:
0 items were added to the queue.
Extracted 1 items from the queue, queue has 95 items left
>>>
这里发生了什么?为什么不是所有物品都被倾倒?
答案 0 :(得分:25)
试试这个:
import Queue
import time
def dump_queue(queue):
"""
Empties all pending items in a queue and returns them in a list.
"""
result = []
for i in iter(queue.get, 'STOP'):
result.append(i)
time.sleep(.1)
return result
import multiprocessing
q = multiprocessing.Queue()
for i in range(100):
q.put([range(200) for j in range(100)])
q.put('STOP')
l=dump_queue(q)
print len(l)
多处理队列有一个内部缓冲区,它有一个馈线线程,可以从缓冲区中取出工作并将其刷新到管道。如果没有刷新所有对象,我可以看到一个过早提升Empty的情况。使用标记来指示队列的结束是安全的(并且可靠)。另外,使用iter(get,sentinel)习语比依赖Empty更好。
我不喜欢它因为冲洗时间而可能会升空(我添加了time.sleep(.1)以允许上下文切换到馈线线程,你可能不需要它,它可以在没有它的情况下工作 - 它是释放GIL的习惯。)
答案 1 :(得分:3)
在某些情况下,我们已经计算了所有内容,我们只想转换队列。
shared_queue = Queue()
shared_queue_list = []
...
join() #All process are joined
while shared_queue.qsize() != 0:
shared_queue_list.append(shared_queue.get())
现在,shared_queue_list将结果转换为列表。