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


110

( 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()메서드 와 이름 만 공유 합니까?


2
내가 아는 한, 그것은 주 스레드를 보유하고 자식 프로세스가 완료 될 때까지 기다린 다음 주 스레드의 리소스를 다시 결합합니다. 대부분 깨끗한 종료를 수행합니다.
abhishekgarg

아 말이 되네요. 그래서 실제 CPU, Memory resources는 부모 프로세스에서 분리되고 join자식 프로세스가 완료된 후 다시 돌아가는 것입니까?
MikeiLL

네, 그게 무슨 일입니다. 당신이 다시 가입하지 않는 경우에 따라서, 때 자식 프로세스는 소멸 또는 죽은 공정으로 단지 거짓말을 완료
abhishekgarg

@abhishekgarg 사실이 아닙니다. 기본 프로세스가 완료되면 하위 프로세스가 암시 적으로 결합됩니다.
dano

@dano, 나는 또한 파이썬을 배우고 있으며 테스트에서 찾은 것을 공유했습니다. 내 테스트에서 나는 결코 끝나지 않는 메인 프로세스가 있었기 때문에 아마도 그 자식 프로세스가 사라진 것으로 보았습니다.
abhishekgarg

답변:


125

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 ()가 호출되기 전에 설정되어야합니다.

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

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


6
나는 그것이 p.daemon=True"메인 프로그램의 종료를 막지 않고 실행되는 백그라운드 프로세스를 시작하는 것" 이라는 것을 이해하고 있었습니다. 그러나 "데몬 프로세스가 메인 프로그램이 종료되기 전에 자동으로 종료된다"면 정확히 어떤 용도로 사용됩니까?
MikeiLL

8
@MikeiLL 기본적으로 부모 프로세스가 실행되는 동안 백그라운드에서 진행하려는 모든 작업은 기본 프로그램을 종료하기 전에 정상적으로 정리할 필요가 없습니다. 아마도 소켓 또는 하드웨어 장치에서 데이터를 읽고 큐를 통해 해당 데이터를 부모에게 다시 공급하거나 특정 목적을 위해 백그라운드에서 처리하는 작업자 프로세스일까요? 일반적으로 daemonic자식 프로세스 를 사용하는 것은 그다지 안전하지 않다고 말하고 싶습니다 . 프로세스가 열려있는 리소스를 정리하지 않고 종료되기 때문입니다 .. (계속).
dano

7
@MikeiLL 더 나은 방법은 주 프로세스를 종료하기 전에 어린이에게 정리 및 종료 신호를 보내는 것입니다. 부모가 종료 될 때 데몬 자식 프로세스를 실행 상태로 두는 것이 합리적이라고 생각할 수 있지만 multiprocessingAPI는 threadingAPI를 가능한 한 가깝게 모방하도록 설계되었습니다 . 데몬 threading.Thread개체는 기본 스레드가 종료되는 즉시 종료되므로 데몬 multiprocesing.Process개체는 동일한 방식으로 작동합니다.
dano

38

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

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

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


2
객체가 완료 되기를 기다리는 데 사용되는 이름 join()이기 때문에 이름을 join()사용 threading.Thread하고 multiprocessingAPI는 threading가능한 한 API 를 모방하기위한 것 입니다.
dano

두 번째 진술은 현재 프로젝트에서 다루고있는 문제를 다룹니다.
MikeiLL

주 스레드가 하위 프로세스가 완료 될 때까지 기다리는 부분을 이해하지만 그런 종류가 비동기 실행의 목적을 무효화하지 않습니까? 독립적으로 (하위 작업 또는 프로세스) 실행을 완료해야하지 않습니까?
Apurva Kunkulol

1
@ApurvaKunkulol 사용 방법 join()에 따라 다르지만 주 스레드가 하위 스레드 작업의 결과를 필요로하는 경우에 필요합니다. 예를 들어, 무언가를 렌더링하고 4 개의 하위 프로세스 각각에 최종 이미지의 1/4을 할당하고 완료되면 전체 이미지를 표시하려는 경우입니다.
Russell Borogove

트윗 담아 가기 알겠습니다. 그렇다면 여기서 비동기 활동의 의미는 약간 다릅니다. 이는 하위 프로세스가 주 스레드와 동시에 작업을 수행하는 반면 주 스레드도 하위 프로세스를 기다릴 때만 기다리지 않고 작업을 수행한다는 사실을 의미해야합니다.
Apurva Kunkulol

12

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

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

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

"fork"및 "join"이라는 이름은 1963 년부터 다중 처리에서 이러한 의미로 사용되었습니다 .


따라서 어떤면에서이 단어 join의 사용은 다른 방법과는 반대로 연결을 참조하는 데 사용되기 이전에 사용되었을 수 있습니다.
MikeiLL

1
다중 처리에서의 사용에서 파생 된 연결에서의 사용은 거의 없습니다. 오히려 두 감각 모두 평범한 영어 단어의 의미와는 별도로 파생됩니다.
Russell Borogove

2

join()작업자 프로세스가 종료 될 때까지 기다리는 데 사용됩니다. 을 ( 를) 사용하기 전에 close()또는 호출해야합니다 .terminate()join()

@Russell이 언급 한 것처럼 조인포크 (하위 프로세스 생성) 의 반대와 같습니다 .

조인을 실행하려면 close()더 이상 작업이 풀에 제출되지 않도록하고 모든 작업이 완료되면 종료해야합니다. 또는 실행 terminate()은 모든 작업자 프로세스를 즉시 중지하여 종료됩니다.

"the child process will sit idle and not terminate, becoming a zombie you must manually kill" 이는 기본 (상위) 프로세스가 종료되었지만 하위 프로세스가 여전히 실행 중이고 완료되면 종료 상태를 반환 할 상위 프로세스가 없을 때 가능합니다.


2

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()

0

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

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

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

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.