multiprocessing.Manager 嵌套共享对象不适用于队列

fin*_*oot 5 python queue memory-management process multiprocessing

模块状态的 Python 文档multiprocessing

版本 3.6 中的更改:共享对象可以嵌套。例如,共享容器对象(例如共享列表)可以包含其他共享对象,这些对象都将由SyncManager.

这确实适用于listdictQueue但是,如果我尝试在共享内创建共享dict,则会收到错误:

>>> from multiprocessing import Manager
>>> m = Manager()
>>> d = m.dict()
>>> d['a'] = m.list()
>>> d['b'] = m.dict()
>>> d['c'] = m.Queue()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 2, in __setitem__
  File "/usr/lib/python3.6/multiprocessing/managers.py", line 772, in _callmethod
    raise convert_to_error(kind, result)
multiprocessing.managers.RemoteError: 
---------------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python3.6/multiprocessing/managers.py", line 228, in serve_client
    request = recv()
  File "/usr/lib/python3.6/multiprocessing/connection.py", line 251, in recv
    return _ForkingPickler.loads(buf.getbuffer())
  File "/usr/lib/python3.6/multiprocessing/managers.py", line 881, in RebuildProxy
    return func(token, serializer, incref=incref, **kwds)
TypeError: AutoProxy() got an unexpected keyword argument 'manager_owned'
---------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

似乎https://hg.python.org/cpython/rev/39e7307f9aee是引入嵌套共享对象的变更集。

Dar*_*aut 5

该错误是由于AutoProxy当前未处理所有BaseProxy参数引起的。有一个尚未合并的拉取请求。您要么需要猴子补丁AutoProxy,要么您查看补丁multiprocessing.managers.py的更改并将其直接应用到您的源代码。

修复补丁中的这两行以防止服务器进程中的内存泄漏非常重要。-标志manager_owned用于让BaseProxy代码知道何时跳过管理器自己拥有的代理的引用增量(通过嵌套)。