Использует ли процесс создания многопроцессорного пакета Python состояние файла при запуске родительского процесса или состояние файла во время нереста процесса? - PullRequest
4 голосов
/ 25 марта 2020

Если у меня есть некоторый код Python с длительным этапом установки, который в конечном итоге порождает процессы, будет ли порожденный процесс основываться на файлах Python в начале родительского процесса или файлах во время нереста?

То есть я запускаю родительский процесс Python. Затем я go и редактирую файлы Python и, наконец, редактирую их до того, как родительский процесс порождает другие процессы. Наконец, родительский процесс порождает дочерние процессы, которые используют код из этих файлов. Будут ли дочерние процессы использовать код, который был при запуске родительского процесса? Или код, какой он был во время нереста процесса?

1 Ответ

3 голосов
/ 29 марта 2020

Ответ на ваш вопрос зависит от операционной системы.

В Linux multiprocessing использует системный вызов fork для создания дочерних процессов. В результате дочерний процесс «наследует» байт-код всех python источников и не перечитывает источники. То есть в Linux ребенок не распознает изменения.

В Windows multiprocessing создает дочерние процессы с использованием _winapi.CreateProcess. Дочерний объект инициализирует себя с нуля, то есть он снова будет читать все исходные файлы, включая измененные.

Доказательство.

Вот небольшой пример, когда основные процессы изменяют один из исходных файлов. files.

somelib.py: выводит идентификатор процесса, который его загружает.

import os

print("SomeLib loaded in process", os.getpid())

test.py: перед порождением дочернего процесса он исправляет somelib.py

from multiprocessing import Process
# somelib prints process ID and, if patched, an extra line
import somelib

def f(name):
    print('hello', name)

if __name__ == '__main__':
    print("The main process is patching SomeLib")
    with open("somelib.py", "a+") as patch:
        patch.write("\n\nprint('SomeLib is patched')")
    p = Process(target=f, args=('bob',))
    # Spawn the the child
    p.start()
    p.join()

Выход в Linux:

SomeLib loaded in process 70
The main process is patching SomeLib
hello bob

somelib.py был изменен, но потомок проигнорировал это из-за fork.

Выход в Windows

SomeLib loaded in process 22512
The main process is patching SomeLib
SomeLib loaded in process 17008
SomeLib is patched
hello bob

Видите? Ребенок с pid 17008 «перезагружен» somelib.py и обработан модифицированным.

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