multiprocessing fork () против spawn ()

Sep 28 2020

Я читал описание двух из документа Python :

порождать

Родительский процесс запускает новый процесс интерпретатора Python. Дочерний процесс наследует только те ресурсы, которые необходимы для запуска метода run () объектов процесса. В частности, ненужные файловые дескрипторы и дескрипторы родительского процесса не будут унаследованы. Запуск процесса с использованием этого метода довольно медленный по сравнению с использованием fork или forkserver. [Доступно в Unix и Windows. По умолчанию в Windows и macOS.]

вилка

Родительский процесс использует os.fork () для разветвления интерпретатора Python. Дочерний процесс, когда он начинается, фактически идентичен родительскому процессу. Все ресурсы родительского процесса наследуются дочерним процессом. Обратите внимание, что безопасное разветвление многопоточного процесса проблематично. [Доступно только в Unix. По умолчанию в Unix.]

И мой вопрос:

  1. дело в том, что форк работает намного быстрее, потому что он не пытается определить, какие ресурсы копировать?
  2. Дело в том, что, поскольку вилка дублирует все, она "тратит" гораздо больше ресурсов по сравнению с spawn ()?

Ответы

3 Darkonaut Sep 28 2020 at 12:25
  1. дело в том, что форк работает намного быстрее, потому что он не пытается определить, какие ресурсы копировать?

Да, это намного быстрее. Ядро может клонировать весь процесс и копирует только измененные страницы памяти целиком . Связывание ресурсов с новым процессом и загрузка интерпретатора с нуля не требуется.

  1. Дело в том, что, поскольку вилка дублирует все, она "тратит" гораздо больше ресурсов по сравнению с spawn ()?

Форк в современных ядрах выполняет только «копирование при записи» и влияет только на те страницы памяти, которые фактически изменяются. Предостережение заключается в том, что «запись» уже включает в себя простой перебор объекта в CPython. Это потому, что счетчик ссылок на объект увеличивается.

Если у вас есть длительные процессы с большим количеством используемых мелких объектов, это может означать, что вы тратите больше памяти, чем при spawn. Как ни странно, я вспоминаю, как Facebook утверждал, что использование памяти значительно сократилось при переключении с «вилки» на «порождение» для их процессов Python.