考虑以下示例:
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。
我已阅读以下问题:
答案 0 :(得分:0)
此行为源于multiprocessing.Pool
。
在内部,当您致电apply_async
时,您将作业放入Pool
调用队列,然后返回AsyncResult
对象,这样您就可以使用get检索计算结果。
然后另一个线程负责腌制你的工作。在此主题中,RuntimeError
已发生,但您已从调用async_apply
返回。因此,它会将结果设置为AsyncResult
作为例外,当您致电get
时会引发该结果。
当您尝试使用具有明确未来对象的concurrent.futures
时,可以更好地理解使用某种未来结果的此行为,并且,IMO是一种更好的设计来处理故障,您可以查询未来的对象是否有失败调用get
函数。