Делает python os.fork использует тот же интерпретатор python?

Я понимаю, что потоки в Python используют один и тот же экземпляр интерпретатора Python. Мой вопрос то же самое с процессом, созданным os.fork? Или каждый процесс, созданный os.fork имеет свой собственный переводчик?

3 ответов


всякий раз, когда вы вилка, весь процесс Python дублируется в памяти (в том числе интерпретатор Python, ваш код и любые библиотеки, текущий стек и т. д.) создание второго процесса-одна из причин, почему разветвление процесса намного дороже, чем создание потока.

Это создает новая копия интерпретатора python.

одним из преимуществ работы двух интерпретаторов python является то, что теперь у вас есть два Gil (Global Interpreter Замки), и поэтому может иметь истинную мульти-обработку на многоядерной системе.

потоки в одном процессе имеют один и тот же GIL, то есть только один работает в данный момент, давая только иллюзию параллелизма.


пока fork действительно создает копию текущего интерпретатора Python, а не работает с тем же самым, обычно это не то, что вы хотите, по крайней мере, не самостоятельно. Среди других проблем:

  • на некоторых платформах могут возникнуть проблемы с разветвлением многопоточных процессов. И некоторые библиотеки (наиболее известные как Cocoa/CoreFoundation от Apple) могут запускать потоки для вас в фоновом режиме или использовать локальные API потоков, даже если у вас есть только один поток и т. д., без ваше знание.
  • некоторые библиотеки предполагают, что каждый процесс будет инициализирован правильно, но если вы fork после инициализации-это не правда. Самое позорное, если вы позволите ssl seed его PRNG в основном процессе, затем вилка, теперь у вас есть потенциально предсказуемые случайные числа, что является большой дырой в вашей безопасности.
  • открытые файловые дескрипторы наследуются (как dups) детьми, с деталями, которые различаются раздражающими способами между платформы.
  • POSIX требует только платформ для реализации очень специфического набора syscalls между fork и exec. Если вы никогда не позвоните exec, вы можете использовать только эти syscalls. Который в основном означает, что вы не можете сделать что-нибудь портабельно.
  • ничего общего с сигналами особенно раздражает и не переносится после fork.

посмотреть POSIX fork или manpage вашей платформы для деталей на эти же вопросы.

правильный ответ почти всегда использовать multiprocessing или concurrent.futures (который оборачивает multiprocessing) или аналогичная сторонняя библиотека.

С 3.4+, вы даже можете указать метод start. The fork метод в основном только звонки fork. The forkserver метод запускает один "чистый" процесс (без потоков, обработчиков сигналов, инициализации SSL и т. д. и от этого у нас появляются новые дети. The spawn способ звонки fork затем exec, или эквивалент, как posix_spawn, чтобы получить вам совершенно новый интерпретатор вместо копии. Таким образом, вы можете начать с fork, ut тогда, если есть какие-либо проблемы, переключитесь на forkserver или spawn и ничего в коде менять. Что довольно мило.


os.fork() эквивалентно fork() syscall во многих ИЦООН. Так что да ваш подпроцесс(ы) будет отделен от родительского и будет иметь другой интерпретатор (что такое).

man fork:

вилка(2)

имя fork-создать дочерний процесс

синопсис # include

   pid_t fork(void);

описание Fork() создает новый процесс путем дублирования процесса. Новый процесс, называемый ребенком, является точной копией вызывающего процесса, называемого родительским, за исключением следующих моментов:

pydoc os.fork():

os.fork() вилка дочернего процесса. Возвращает 0 в дочернем и идентификатор дочернего процесса в Родительском. При возникновении ошибки OSError поднятый.

обратите внимание, что некоторые платформы, включая FreeBSD

Читайте также: ответ Мартин Конечны, как, почему и преимущества "расщепление" :)

для краткости; другие подходы к параллелизму, которые не включают отдельный процесс и, следовательно, отдельный интерпретатор Python, включают: