2 回答

TA贡献1830条经验 获得超3个赞
您的Queue基于代码的代码至少存在两个问题。Pool.apply_async方法返回一个AsyncResult对象,而不是一个进程。您可以调用get该对象来获取相应过程的结果。考虑到这种差异,让我们看看您的代码:
proc = p.apply_async(Test, args=(i,)) # Returns an AsyncResult object
q.put(proc) # won't work
在您的情况下,第二行将始终失败。您放入队列的任何内容都必须是可腌制的,因为multiprocess.Queue使用序列化。这没有很好的文档记录,并且Python 的问题跟踪器中有一个未解决的问题来更新文档。问题是AsyncResult不能腌制。你可以自己试试:
import pickle
import multiprocessing as mp
with mp.Pool() as p:
result = p.apply_async(lambda x: x, (1,))
pickle.dumps(result) # Error
AsyncResult内部包含一些锁定对象,它们不可序列化。让我们转到下一个问题:
while not q.empty():
q.get()
如果我没记错的话,在上面的代码中,您要调用AsyncResult.get而不是Queue.get. 在这种情况下,您必须首先从队列中获取您的对象,然后在您的对象上调用相应的方法。但是,在您的代码中情况并非如此,因为AsyncResult它不可序列化。

TA贡献1876条经验 获得超6个赞
AsyncResult对象不能被腌制,这multiprocessing.Queue是必需的。但是,这里不需要一个,因为队列没有在进程之间共享。这意味着您可以只使用常规的Queue.
from multiprocessing import Pool
#from multiprocessing import Queue
from queue import Queue
class Test(object):
def __init__(self, num):
self.num = num
print('Test({!r}) created'.format(num))
if __name__ == '__main__':
p = Pool()
q = Queue()
for i in range(5):
proc = p.apply_async(Test, args=(i,))
q.put(proc)
p.close()
while not q.empty():
q.get()
p.join()
print('done')
输出:
Test(0)
Test(1)
Test(2)
Test(3)
Test(4)
done
添加回答
举报