Ответ 1
В Windows нет процедуры fork()
, поэтому multiprocessing
импортирует текущий модуль, чтобы получить доступ к функции worker
. Без инструкции if
дочерний процесс запускает собственные дочерние элементы и т.д.
Я работал над следующим примером из Doug Hellmann по многопроцессорности:
import multiprocessing
def worker():
"""worker function"""
print 'Worker'
return
if __name__ == '__main__':
jobs = []
for i in range(5):
p = multiprocessing.Process(target=worker)
jobs.append(p)
p.start()
Когда я попытался запустить его вне оператора if:
import multiprocessing
def worker():
"""worker function"""
print 'Worker'
return
jobs = []
for i in range(5):
p = multiprocessing.Process(target=worker)
jobs.append(p)
p.start()
Он начал нерестовые процессы без остановок, и единственный способ остановить его - перезагрузка!
Почему это произойдет? Почему он не сгенерировал 5 процессов и не вышел? Зачем мне нужен оператор if?
В Windows нет процедуры fork()
, поэтому multiprocessing
импортирует текущий модуль, чтобы получить доступ к функции worker
. Без инструкции if
дочерний процесс запускает собственные дочерние элементы и т.д.
Обратите внимание, что в документации упоминается, что вам нужен оператор if
для Windows (здесь).
Однако в документации не говорится, что это убивает вашу машину почти мгновенно, требуя перезагрузки. Таким образом, это может быть довольно запутанным, особенно если использование multiprocessing
происходит в некоторой функции внутри кода. Независимо от того, насколько глубоко он скрыт, вам все равно нужна проверка if
в главном файле программы. В значительной степени это исключает использование multiprocessing
в любой библиотеке.
multiprocessing
вообще кажется немного грубым. Он может иметь интерфейс интерфейса потока, но в GIL нет простого способа.
Для более сложных задач параллелизации я также рассмотрю модуль subprocess
или некоторые другие библиотеки (например, mpi4py или Parallel Python).
Я не знаю о multiprocessing
, но я подозреваю, что он порождает дочерние процессы, у которых есть другой __name__
глобальный. Удалив тест, вы заставляете каждого ребенка снова запускать процесс нереста.