`apply_async`使“共享队列错误”无法“

时间:2017-07-19 00:50:11

标签: python python-3.x multiprocessing python-multiprocessing

考虑以下示例:

from multiprocessing import Queue, Pool

def work(*args):
    print('work')
    return 0

if __name__ == '__main__':
    queue = Queue()
    pool = Pool(1)
    result = pool.apply_async(work, args=(queue,))
    print(result.get())

这会引发以下RuntimeError

Traceback (most recent call last):
  File "/tmp/test.py", line 11, in <module>
    print(result.get())
  [...]
RuntimeError: Queue objects should only be shared between processes through inheritance

但有趣的是,只有在我尝试get结果时才会引发异常,而不是在“共享”发生时。当我实际共享队列时,评论相应的行会使错误无效,并且work永远不会执行!)。

所以这里是我的问题:为什么只在请求结果时引发此异常,而不是在调用apply_async方法时引发,即使错误似乎被识别,因为永远不会调用目标work函数吗?

看起来异常发生在不同的进程中,并且只有在以请求结果的形式执行进程间通信时才能使主进程可用。然而,我想知道为什么在调度到另一个进程之前没有执行这样的检查。
(如果我在work和主进程中使用队列进行通信,那么这将(静默地)引入死锁。)

Python版本是3.5.2。

我已阅读以下问题:

1 个答案:

答案 0 :(得分:0)

此行为源于multiprocessing.Pool

的设计

在内部,当您致电apply_async时,您将作业放入Pool调用队列,然后返回AsyncResult对象,这样您就可以使用get检索计算结果。 然后另一个线程负责腌制你的工作。在此主题中,RuntimeError已发生,但您已从调用async_apply返回。因此,它会将结果设置为AsyncResult作为例外,当您致电get时会引发该结果。

当您尝试使用具有明确未来对象的concurrent.futures时,可以更好地理解使用某种未来结果的此行为,并且,IMO是一种更好的设计来处理故障,您可以查询未来的对象是否有失败调用get函数。