Правда ли, что в многопроцессорной обработке каждый процесс получает свой собственный GIL в CPython? Насколько это отличается от создания новых сред выполнения? - PullRequest
4 голосов
/ 15 февраля 2020

Есть ли какие-либо предостережения к этому? У меня есть несколько вопросов, связанных с этим.

Насколько дорого создавать больше GIL? Отличается ли это от создания отдельной python среды выполнения? Как только будет создан новый GIL, будет ли он создавать все (объекты, переменные, стек, кучу) с нуля, как требуется в этом процессе, или будет создана копия всего в текущей куче и стек? (Сборка мусора будет работать со сбоями, если они работают с одними и теми же объектами.) Копируются ли фрагменты кода, выполняемые на новые ядра ЦП? Кроме того, могу ли я связать один GIL с одним ядром процессора?

Теперь копирование - это довольно трудоемкая задача (поправьте меня, если я ошибаюсь), какой будет порог, чтобы решить, стоит ли go для многопроцессорной обработки?

PS: я говорю о CPython, но, пожалуйста, не стесняйтесь распространять ответ на то, что вы считаете необходимым.

1 Ответ

2 голосов
/ 15 февраля 2020

Краткий ответ на первый заглавный вопрос: Да. Каждый процесс имеет свою собственную глобальную блокировку интерпретации. После этого все становится сложным и на самом деле не столько Python вопросом, сколько вопросом вашего базового процесса.

На Linux, это должно быть дешевле, а порождать новые процессы через multiprocessing чем запуск нового интерпретатора Python (с нуля):

  • вы fork() родительский процесс (примечание: clone() на самом деле используется в эти дни), ребенок уже имеет ваш код и начинает с копии адресного пространства родителей -> так как вы фактически порождаете другой экземпляр вашего запущенного процесса, нет необходимости execve() (и все накладные расходы связан с этим) и повторно заполняет его содержимое.
  • на самом деле, когда мы говорим, что копия адресного пространства, оно фактически не копируется полностью, а скорее использует копирование при записи; поэтому, если вы не изменили его, вам вообще не нужно его копировать.

По этой причине у меня было бы ощущение, что многопроцессорная обработка почти всегда будет более эффективной, чем запуск совершенно нового Python переводчик с нуля. В конце концов, даже если вы запустили новый интерпретатор (предположительно из запущенного процесса), он сначала выполняет fork() / clone(), включая «копирование» адресного пространства родителя, прежде чем перейти на execve().

Но на самом деле это может варьироваться и зависит от того, как ваша базовая ОС обрабатывает создание новых процессов, а также управление памятью.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...