[python] 파이썬 멀티 프로세싱 모듈의 .join () 메소드는 정확히 무엇을합니까?

( PMOTW 기사에서 ) Python Multiprocessing 에 대해 배우고이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()메서드 와 이름 만 공유 합니까?



답변

join()방법은 다음과 함께 사용했을 때 threadingmultiprocessing, 관련이 없습니다 str.join()– 실제로 함께 무엇을 연결 아니에요. 오히려 “이 [스레드 / 프로세스]가 완료 될 때까지 기다리십시오”를 의미합니다. 이름은 join때문에 사용되는 multiprocessing모듈의 API가 유사으로 보는 의미 threading모듈의 API 및 threading모듈 사용 join의를위한 Thread객체입니다. join“스레드가 완료 될 때까지 기다림”을 의미 하는 용어 를 사용하는 것은 많은 프로그래밍 언어에서 일반적이므로 Python도이를 채택했습니다.

이제 호출이있는 경우와없는 경우 모두 20 초 지연이 나타나는 이유 join()는 기본적으로 기본 프로세스가 종료 할 준비가되면 join()실행중인 모든 multiprocessing.Process인스턴스를 암시 적으로 호출하기 때문입니다 . 이것은 multiprocessing문서에 명확하게 명시되어 있지는 않지만 프로그래밍 가이드 라인 섹션에 언급되어 있습니다.

비 데모닉 프로세스는 자동으로 결합됩니다.

프로세스를 시작 하기 전에 daemon에 플래그를 설정하여이 동작을 재정의 할 수 있습니다 .ProcessTrue

p = Process(target=say_hello)
p.daemon = True
p.start()
# Both parent and child will exit here, since the main process has completed.

그렇게 하면 기본 프로세스가 완료되는 즉시 하위 프로세스 가 종료됩니다 .

악마

프로세스의 데몬 플래그, 부울 값. start ()가 호출되기 전에 설정되어야합니다.

초기 값은 생성 프로세스에서 상속됩니다.

프로세스가 종료되면 모든 데몬 자식 프로세스를 종료하려고합니다.


답변

이 없으면 join()기본 프로세스가 하위 프로세스보다 먼저 완료 될 수 있습니다. 어떤 상황에서 좀비가되는지 잘 모르겠습니다.

의 주요 목적은 join()기본 프로세스가 하위 프로세스의 작업에 의존하는 작업을 수행하기 전에 하위 프로세스가 완료되었는지 확인하는 것입니다.

의 어원은 자식 프로세스를 생성하기위한 Unix 제품군 운영 체제의 일반적인 용어 인의 join()반대 fork라는 것입니다. 단일 프로세스가 여러 개로 “포크”된 다음 다시 하나로 “결합”됩니다.


답변

무엇을하는지 자세히 설명하지는 않겠습니다. join여기에 어원과 그 뒤에 숨어있는 직감이 있습니다. 이는 의미를 더 쉽게 기억할 수 있도록 도와줍니다.

실행은 하나가 마스터, 나머지 작업자 (또는 “슬레이브”) 인 여러 프로세스로 ” 포크 ” 된다는 것입니다 . 작업자가 완료되면 직렬 실행이 재개 될 수 있도록 마스터에 “조인”됩니다.

join메서드는 마스터 프로세스가 작업자가 참여할 때까지 기다리도록합니다. 이 메서드는 마스터에서 발생하는 실제 동작이므로 “대기”라고하는 것이 더 좋을 수 있습니다 (POSIX 스레드에서 “조인”이라고도 부르지 만 POSIX에서 호출 됨). 결합은 스레드가 제대로 협력하는 효과로만 발생하며 마스터 가 수행 하는 작업은 아닙니다 .

“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" 이는 기본 (상위) 프로세스가 종료되었지만 하위 프로세스가 여전히 실행 중이고 완료되면 종료 상태를 반환 할 상위 프로세스가 없을 때 가능합니다.


답변

join()호출은 모든 다중 처리 프로세스가 완료되기 전에 코드의 후속 줄 이 호출되지 않도록합니다.

예를 들어,없이 join()다음 코드는 restart_program()프로세스가 완료되기 전에도 호출됩니다 . 이는 비동기와 유사하며 우리가 원하는 것은 아닙니다 (시도 할 수 있음).

num_processes = 5

for i in range(num_processes):
    p = multiprocessing.Process(target=calculate_stuff, args=(i,))
    p.start()
    processes.append(p)
for p in processes:
    p.join() # call to ensure subsequent line (e.g. restart_program) 
             # is not called until all processes finish

restart_program()


답변

프로세스가 작업을 완료하고 종료 할 때까지 기다리려면 join () 메서드를 사용하십시오.

참고 프로세스를 종료 한 후 프로세스를 join ()하는 것이 중요합니다. 백그라운드 기계가 종료를 반영하도록 개체의 상태를 업데이트 할 시간을 제공하기 위해서입니다.

이것은 제가 이해하는 데 도움이되는 좋은 예입니다. 여기

내가 개인적으로 알아 차린 한 가지는 아이가 multiprocessing.Process()처음에 사용하는 요점을 무너 뜨린 join () 메서드를 사용하여 프로세스를 완료 할 때까지 내 주요 프로세스가 일시 중지되었다는 것 입니다.


답변