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

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

Ответ 1

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

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

Одним из преимуществ использования двух интерпретаторов python является то, что теперь у вас есть два GIL (Global Interpreter Locks) и, следовательно, может иметь истинную многопроцессорную обработку в многоядерной системе.

В потоках одного процесса используется один и тот же GIL, что означает, что только один выполняется в данный момент, давая только иллюзию parallelism.

Ответ 2

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

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

Подробнее об этих проблемах см. POSIX fork или на странице руководства по платформе.

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

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

Ответ 3

os.fork() эквивалентен syscall fork() во многих UNIC (es). Итак, да ваш подпроцесс будет отделен от родителя и иметь другой интерпретатор (как таковой).

man fork:

ВИЛКИ (2)

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

СИНТАКСИС        #include

   pid_t fork(void);

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

pydoc os.fork():

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

Обратите внимание, что некоторые платформы, включая FreeBSD <= 6.3, Cygwin и OS/2 EMX имеют известные проблемы при использовании fork() из потока.

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

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