请看下面的例子:`apply_async`沉默“共享队列错误”
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
永远不会执行!)时,评论相应的线路将使错误消失。
所以这里去我的问题:为什么当请求的结果是这样的例外,只是提出,而不是当即使错误似乎是公认的,因为目标work
功能从来没有所谓的apply_async
方法被调用?
看起来异常发生在不同的进程中,并且只能在进程间通信以请求结果的形式执行时才可用于主进程。然而,然而,我想知道为什么在调度到另一个过程之前不执行这种检查。
(如果我用在两个work
队列和主处理用于通信那么这将(静默)引入死锁。)
Python版本是3.5.2。
我已经阅读了以下问题:
- Sharing many queues among processes in Python
- How do you pass a Queue reference to a function managed by pool.map_async()?
- Sharing a result queue among several processes
- Python multiprocessing: RuntimeError: “Queue objects should only be shared between processes through inheritance”
- Python sharing a lock between processes
谢谢你的回答!但我有个问题。如果'Queue'对象不能通过参数在进程之间共享,为什么我们可以通过'multiprocessing'完成这个操作。Process'对象(参见[本文档示例 - > Queues](https://docs.python.org/3/library/multiprocessing.html#exchanging-objects-between-processes))?这不会引发'RuntimeError'并且工作正常,所以区别在哪里?参数必须转移到其他进程中,就像“Pool”一样。酸洗在这里呢? –
在'Pool'中,当你实例化时,这个过程就会产生。因此,当你调用'apply_async'时,'Process'已经启动。你可以使用'initializer'和'initargs'参数在'Pool'中传递'Queue'来在我认为的子进程中声明一个全局的'Queue'。 –
您也可以将'Queue'声明为模块的全局属性,以避免混淆'initializer'。 'pickle'应该能够处理我认为的这种情况。 –