我实际上很难相信我遇到了问题,我有,它似乎是一个在Python多处理模块中的大错误。无论如何,我遇到的问题是,只要我将multiprocessing.Queue传递给multiprocessing.Pool worker作为参数,池工作人员就不会执行其代码。即使是在python docs中找到的示例代码的稍微修改版本的非常简单的测试中,我也能够重现此错误。multiprocessing.Queue作为参数池的工人中止工作人员的执行
下面是示例代码队列的原始版本:
from multiprocessing import Process, Queue
def f(q):
q.put([42, None, 'hello'])
if __name__ == '__main__':
q = Queue()
p = Process(target=f, args=(q,))
p.start()
print(q.get()) # prints "[42, None, 'hello']"
p.join()
这里是我的队列的示例代码修改后的版本:
from multiprocessing import Queue, Pool
def f(q):
q.put([42, None, 'hello'])
if __name__ == '__main__':
q = Queue()
p = Pool(1)
p.apply_async(f,args=(q,))
print(q.get()) # prints "[42, None, 'hello']"
p.close()
p.join()
所有我做的是使PA大小为1的进程池,而不是多进程。进程对象,结果是代码永远挂在打印语句上,因为没有任何内容写入队列!当然,我测试它的原始形式,它工作正常。我的操作系统是Windows 10,我的Python版本是3.5.x,任何人都有任何想法,为什么发生这种情况?
更新:仍然不知道为什么这个示例代码与multiprocessing.process,而不是一个multiprocessing.Pool,但我发现work around我满足(亚历克斯Martelli的答案)。显然你可以创建一个多处理的全局列表。并且要传递每个进程和索引来使用,我将避免使用一个受管队列,因为它们比较慢。感谢Guest向我展示链接。
你可能想看看[#1](https://stackoverflow.com/a/30039159/3767239),[# 2](https://stackoverflow.com/q/3217002/3767239),[#3](https://stackoverflow.com/q/9908781/3767239),[#4](https://stackoverflow.com/a/42659752/3767239),[#5](https://stackoverflow.com/a/25558333/3767239)。看起来原因是'Queue'实例不能被腌制。但是我不明白为什么这会使流程的底层队列陷入僵局。使用池大小为2的'Ctrl + C'显示它被卡在'task = inqueue.get()'它将请求目标函数的地方。这有点令人费解。 –
请注意,对于异步编程,您不需要手动处理结果队列 - apply_async会返回['AsyncResult'](https://docs.python.org/3/library/multiprocessing.html#multiprocessing.pool .AsyncResult)可以用来得到结果的实例:'result.get()'。这使用了一个基础结果(out-)队列,所以你只需要在你的目标函数中“返回”。同样,如果你使用'result.get()',并且你将'Queue'实例作为参数传递给目标函数,它将引发'RuntimeError'。不过,我很好奇为什么这不会发生在你的例子。 –
看到我的评论给你的答案。我的目标不是“结果队列”,这仅仅是一个简单的例子。我需要一个连续写入和处理的队列。 – profPlum