Возврат больших объектов из дочерних процессов в многопроцессорной среде Python
Я работаю с многопроцессорным Python для порождения некоторых рабочих. Каждый из них должен возвращать массив размером в несколько МБ.
- Правильно ли, что, поскольку мой возвращаемый массив создан в дочернем процессе, его необходимо скопировать обратно в память родителя, когда процесс завершится? (кажется, это займет некоторое время, но это может быть неприятной проблемой)
- Существует ли механизм, позволяющий родительскому и дочернему элементам получать доступ к одному и тому же объекту в памяти? (синхронизация не является проблемой, поскольку только один дочерний элемент будет иметь доступ к каждому объекту)
Боюсь, у меня есть несколько пробелов в том, как python реализует многопроцессорность, и попытка убедить pypy играть хорошо, не облегчает ситуацию. Спасибо!
1 ответ
Да, если возвращаемый массив создается в дочернем процессе, он должен быть отправлен родительскому элементу путем его выборки, отправив выбранные байты обратно родительскому элементу через Pipe
, а затем открепление объекта в родительском. Для больших объектов это довольно медленно в CPython, так что это не просто проблема PyPy. Вполне возможно, что производительность в PyPy хуже; Я не пробовал сравнивать два, но эта ошибка PyPy, кажется, предполагает, что multiprocessing
в PyPy медленнее, чем в CPython.
В CPython есть способ выделить ctypes
объекты в общей памяти, через multiprocessing.sharedctypes
, PyPy, кажется, также поддерживает этот API. Ограничение (очевидно) заключается в том, что вы ограничены ctypes
объекты.
Существует также multiprocessing.Manager
, что позволит вам создать общий массив / список объектов в Manager
процесс, и тогда и родитель и потомок могут получить доступ к общему списку через Proxy
объект. Недостатком является то, что производительность чтения / записи для объекта намного ниже, чем для локального объекта, или даже если это был примерно эквивалентный объект, созданный с использованием multiprocessing.sharedctypes
,