Многопроцессорные вложенные общие объекты Python не работают с очередью - PullRequest
1 голос
/ 22 июня 2019

Документы Python для модуля multiprocessing:

Общие объекты могут быть вложенными. Например, общий контейнерный объект, такой как общий список, может содержать другие общие объекты, которые будут управляться и синхронизироваться SyncManager.

Это работает с list и dict. Однако, если я пытаюсь создать общий Queue внутри общего 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'
---------------------------------------------------------------------------

Похоже, https://hg.python.org/cpython/rev/39e7307f9aee - это набор изменений, который представил вложенные общие объекты.

1 Ответ

1 голос
/ 23 июня 2019

Ошибка вызвана тем, что AutoProxy в настоящее время не обрабатывает все BaseProxy аргументы. Существует запрос на получение , который еще не был объединен. Вам нужно либо обезьяньим патчем AutoProxy, либо заглянуть в multiprocessing.managers.py и применить изменения в патче здесь непосредственно к исходному коду.

Очень важно исправить обе строки в патче, чтобы предотвратить утечку памяти в процессе сервера. Флаг manager_owned используется, чтобы сообщить коду BaseProxy, когда пропустить приращение ссылки для прокси-сервера, которым владеет менеджер (через вложение).

...