#python #multiprocessing #deep-copy
#python #многопроцессорная обработка #глубокое копирование
Вопрос:
from multiprocessing import Process
# c is a container
p = Process(target = f, args = (c,))
p.start()
Я предполагаю, что глубокая копия c
передается функции f
, потому что мелкая копия не имела бы смысла в случае нового процесса (у нового процесса нет доступа к данным из вызывающего процесса).
Но как определяется эта глубокая копия? В документации есть целый набор примечаний copy.deepcopy()
, применимы ли все эти примечания и здесь? В multiprocessing
документации ничего не сказано…
Ответ №1:
Когда вы создаете Process
экземпляр, под капотом Python выдает fork()
. Это создает дочерний процесс, пространство памяти которого является точной копией родительского — так что копируется все, что существовало на момент форка.
В Linux это стало эффективным благодаря «копированию при записи». Со страницы руководства по форку:
fork() создает дочерний процесс, который отличается от родительского процесса только своими PID и PPID, а также тем фактом, что для использования ресурсов установлено значение 0. Блокировки файлов и ожидающие сигналы не наследуются.
В Linux fork() реализован с использованием копирования страниц при записи, поэтому единственное наказание, которому он подвергается, — это время и память, необходимые для дублирования таблиц родительских страниц и создания уникальной структуры задач для дочернего элемента.
Комментарии:
1. 1. Обратите внимание, что Windows использует другой механизм, чем
fork()
, но эффекты похожи.2. Это правильно, но нужно упомянуть, что это неправда, что ничего не копируется. Сборщик мусора Python должен поддерживать количество ссылок. Однако затраты памяти на это незначительны (я думаю, 4 КБ на каждый процесс).
3. Старая информация выше: Из документов python : > Изменено в версии 3.4: spawn добавлен на всех платформах unix, а forkserver добавлен для некоторых платформ unix. Дочерние процессы больше не наследуют все родительские наследуемые дескрипторы в Windows.