Многопроцессорная бомба - PullRequest
36 голосов
/ 23 апреля 2010

Я работал над следующим примером из учебника Дуга Хеллмана по многопроцессорности:

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?

Ответы [ 3 ]

46 голосов
/ 23 апреля 2010

В Windows подпрограмма fork() отсутствует, поэтому multiprocessing импортирует текущий модуль, чтобы получить доступ к функции worker. Без оператора if дочерний процесс запускает своих собственных потомков и т. Д.

8 голосов
/ 23 апреля 2010

Обратите внимание, что в документации упоминается, что вам необходим оператор if для окон ( здесь ).

Однако в документации не говорится, что это убивает вашу машину практически мгновенно,требующий перезагрузки.Так что это может быть довольно запутанным, особенно если использование multiprocessing происходит в какой-то функции глубоко внутри кода.Независимо от того, насколько глубоко он скрыт, вам все равно нужна проверка if в основном файле программы.Это в значительной степени исключает использование multiprocessing в любой библиотеке.

multiprocessing в целом кажется немного грубым.Он может иметь интерфейс интерфейса потока, но просто нет способа обойти GIL.

Для более сложных задач распараллеливания я бы также посмотрел на модуль subprocess или некоторые другие библиотеки (например, * 1015).* mpi4py или Параллельный Python ).

4 голосов
/ 23 апреля 2010

Я не знаю о multiprocessing, но я подозреваю, что он порождает дочерние процессы, которые имеют другой __name__ глобальный. Убрав тест, вы заставляете каждого ребенка снова запускать процесс нереста.

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