Подтвердить что ты не робот

Что такое модуль многопроцессорности Python.join() Doing?

Изучение Python Multiprocessing (из статья 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() конкатенированием чего-либо здесь? Это конкатенирование процесса с его завершением? Или просто передайте имя с помощью собственного метода .join() на языке Python?

4b9b3361

Ответ 1

Метод join(), когда он используется с threading или multiprocessing, не связан с str.join() - он фактически не объединяет ничего вместе. Скорее, это просто означает "дождитесь завершения этого [потока/процесса]". Имя join используется, потому что API модуля multiprocessing должен выглядеть похожим на API модуля threading, а модуль threading использует join для своего объекта Thread. Использование термина join для обозначения "ожидание завершения потока" является общим для многих языков программирования, поэтому Python просто принял его также.

Теперь причина, по которой вы видите 20-секундную задержку как с вызовом join(), так и без него, заключается в том, что по умолчанию, когда основной процесс готов к завершению, он будет неявно вызывать join() для всех запущенных multiprocessing.Process экземпляров. Это не так четко указано в документах multiprocessing, как и должно быть, но оно упоминается в разделе Руководства по программированию:

Помните также, что не-демонические процессы будут автоматически присоединился.

Вы можете переопределить это поведение, установив флаг 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().

Начальное значение наследуется от процесса создания.

Когда процесс завершается, он пытается завершить все свои демонические дочерние процессы.

Ответ 2

Без join() основной процесс может завершиться до того, как будет выполняться дочерний процесс. Я не уверен, при каких обстоятельствах это приводит к зомбизму.

Основной целью join() является обеспечение того, чтобы дочерний процесс завершился до того, как основной процесс выполнит все, что зависит от работы дочернего процесса.

Этимология join() заключается в том, что она противоположна fork, что является общим термином в операционных системах семейства Unix для создания дочерних процессов. Один процесс "вилки" в несколько, затем "присоединяется" обратно к одному.

Ответ 3

Я не буду подробно объяснять, что делает join, но здесь этимология и интуиция за ней, что должно помочь вам легче запомнить ее смысл.

Идея заключается в том, что выполнение вилок "в несколько процессов, одним из которых является мастер, остальные работники (или" подчиненные "). Когда рабочие завершены, они" присоединяются" к мастеру, чтобы серийное исполнение могло быть возобновлено.

Метод join заставляет мастер-процесс ждать, пока работник присоединится к нему. Метод можно было бы лучше назвать "ждать", так как это фактическое поведение, которое он вызывает в master (и то, что он вызвал в POSIX, хотя потоки POSIX также называют его "join" ). Присоединение происходит только как эффект взаимодействующих потоков, это не то, что делает мастер.

Имена "fork" и "join" использовались с этим значением при многопроцессорной обработке с 1963 года.