Я понимаю, что потоки в Python используют один и тот же экземпляр интерпретатора Python. Мой вопрос - это то же самое с процессом, созданным os.fork? Или каждый процесс, созданный os.fork, имеет свой собственный интерпретатор?
Использует ли python os.fork тот же интерпретатор python?
Ответ 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). Итак, да ваш подпроцесс будет отделен от родителя и иметь другой интерпретатор (как таковой).
ВИЛКИ (2)
NAME fork - создать дочерний процесс
СИНТАКСИС #include
pid_t fork(void);ОПИСАНИЕ fork() создает новый процесс путем дублирования вызывающего процесса. Новый процесс, называемый ребенком, является точной копией вызывающего процесса, называемой родительским, за исключением следующих точек:
os.fork()Выполните дочерний процесс. Верните 0 в ребенка и id дочернего процесса в родительском элементе. Если возникает ошибка OSError поднят.Обратите внимание, что некоторые платформы, включая FreeBSD <= 6.3, Cygwin и OS/2 EMX имеют известные проблемы при использовании fork() из потока.
Смотрите также: Мартин Конечный ответ о том, почему и преимущества "разветвления":)
Для краткости; другие подходы к concurrency, которые не связаны с отдельным процессом, поэтому отдельный интерпретатор Python включает в себя:
- Зеленые или легкие потоки; ala greenlet
- Генераторы Coroutines ala Python и новый Python 3+
yield from - Async I/O ala asyncio, Twisted, circuits и т.д.