Что именно делает метод Python multiprocessing Module. join ()?
изучение Python многопроцессорная обработка (от статья PMOTW) и хотел бы некоторые разъяснения о том, что именно join() метод делает.
на старый учебник с 2008 года в нем говорится, что без p.join() вызовите код ниже, "дочерний процесс будет сидеть без дела и не завершится, став зомби, которого вы должны вручную убить".
from multiprocessing import Process
def say_hello(name='world'):
print "Hello, %s" % name
p = Process(target=say_hello)
p.start()
p.join()
я добавил распечатку PID а также time.sleep чтобы проверить и насколько я могу судить, процесс завершается сам по себе:
from multiprocessing import Process
import sys
import time
def say_hello(name='world'):
print "Hello, %s" % name
print 'Starting:', p.name, p.pid
sys.stdout.flush()
print 'Exiting :', p.name, p.pid
sys.stdout.flush()
time.sleep(20)
p = Process(target=say_hello)
p.start()
# no p.join()
в течение 20 секунд:
936 ttys000 0:00.05 /Library/Frameworks/Python.framework/Versions/2.7/Reso
938 ttys000 0:00.00 /Library/Frameworks/Python.framework/Versions/2.7/Reso
947 ttys001 0:00.13 -bash
спустя 20 секунд:
947 ttys001 0:00.13 -bash
поведение то же самое с p.join() добавлены в конец файла. Python модуль недели предлагает очень читаемое объяснение модуля; " чтобы дождаться завершения процесса и выхода из него, используйте метод join ().", но похоже, что по крайней мере OS X делал это в любом случае.
Я также задаюсь вопросом о названии метода. Это .join() метод конкатенации что-нибудь здесь? Это сцепление процесса с его концом? Или он просто разделяет имя с родным Python .join() способ?
4 ответов:
The
join()метод, при использованииthreadingилиmultiprocessingне относится кstr.join()- это на самом деле не все объединения. Скорее, это просто означает " дождитесь завершения этого [потока/процесса]". Имяjoin, потому чтоmultiprocessingAPI модуля должен выглядеть так же, как иthreadingAPI модуля, иthreadingмодуль используетjoinдля своего :Помните также, что не демоническими процессы будут автоматически присоединился.
вы можете переопределить это поведение, установив
daemonфлагProcessдоTrueперед началом процесса:p = Process(target=say_hello) p.daemon = True p.start() # Both parent and child will exit here, since the main process has completed.если вы это сделаете, дочерний процесс будет прекращено, как только завершится основной процесс:
демон
флаг демона процесса, логическое значение. Это должно быть установлено ранее start () is называемый.
начальное значение наследуется от процесса создания.
когда процесс завершается, он пытается завершить все свои демонические дочерний процесс.
без
join(), основной процесс может завершиться до того, как это сделает дочерний процесс. Я не уверен, при каких обстоятельствах это приводит к зомбизму.основная цель
join()должен гарантировать, что дочерний процесс завершен до того, как основной процесс сделает все, что зависит от работы дочернего процесса.этимология
join()что этоfork, что является общим термином в операционных системах семейства Unix для создания дочерних процессы. Один процесс "разветвляется" на несколько, а затем "соединяется" обратно в один.
Я не буду подробно объяснять, что
joinделает, но вот этимология и интуиция за ним, которые должны помочь вам запомнить его значение более легко.идея в том, что исполнение"вилки" в несколько процессов, из которых один является хозяином, остальные рабочие (или "рабы"). Когда рабочие закончили, они" присоединяются " к мастеру, чтобы последовательное выполнение могло быть возобновлено.
The
joinметод заставляет главный процесс ждать a рабочий, чтобы присоединиться к нему. Метод лучше было бы назвать "wait", так как это фактическое поведение, которое он вызывает в Мастере (и это то, что он называется в POSIX, хотя потоки POSIX также называют его" join"). Соединение происходит только в результате правильного взаимодействия потоков, это не то, что мастер тут.имена " fork "и" join " были использованы с этим значением в многопроцессорной обработке С 1963 года.
join()используется для ожидания выхода рабочих процессов. Надо позвонитьclose()илиterminate()перед использованиемjoin().как упоминал @ Russell вступить это как противоположность вилки (который порождает подпроцессы).
для соединения для запуска вы должны запустить
close()что предотвратит отправку дополнительных задач в пул и завершит работу после завершения всех задач. Кроме того, работаетterminate()просто выйдет, остановив всех работников процессы сразу же.
"the child process will sit idle and not terminate, becoming a zombie you must manually kill"это возможно, когда основной (родительский) процесс завершается, но дочерний процесс все еще работает, и после его завершения у него нет родительского процесса, чтобы вернуть его статус выхода.
Comments