2017-09-05 7 views
5

Pool의 차이점은 multiprocessing입니다. 내가 볼Python 멀티 프로세싱 모듈에서 ThreadPool과 Pool의 차이점

from multiprocessing.pool import ThreadPool 
import os, time 

print("hi outside of main()") 

def hello(x): 
    print("inside hello()") 
    print("Proccess id: ", os.getpid()) 
    time.sleep(3) 
    return x*x 

if __name__ == "__main__": 
    p = ThreadPool(5) 
    pool_output = p.map(hello, range(3)) 

    print(pool_output) 

"ThreadPool이"로

hi outside of main() 
hi outside of main() 
hi outside of main() 
hi outside of main() 
hi outside of main() 
hi outside of main() 
inside hello() 
Proccess id: 13268 
inside hello() 
Proccess id: 11104 
inside hello() 
Proccess id: 13064 
[0, 1, 4] 

: 나는 다음과 같은 출력을 볼

from multiprocessing import Pool 
import os, time 

print("hi outside of main()") 

def hello(x): 
    print("inside hello()") 
    print("Proccess id: ", os.getpid()) 
    time.sleep(3) 
    return x*x 

if __name__ == "__main__": 
    p = Pool(5) 
    pool_output = p.map(hello, range(3)) 

    print(pool_output) 

: 내 코드를하려고하면,이 메인 내가 볼 차이 다음 출력 :

hi outside of main() 
inside hello() 
inside hello() 
Proccess id: 15204 
Proccess id: 15204 
inside hello() 
Proccess id: 15204 
[0, 1, 4] 

내 질문 TIONS은 다음과 같습니다

  • 은 왜 "외부 __main의 __은()"를 Pool의 때마다 실행됩니다?

  • multiprocessing.pool.ThreadPool 새 프로세스가 생성되지 않습니까? 단지 새로운 스레드를 생성합니까?

  • 그렇다면 을 사용하는 것과 단지 threading 모듈을 사용하는 것의 차이점은 무엇입니까?

어디서나 ThreadPool에 대한 공식 설명서가 보이지 않지만 누군가 내가 도와 줄 수 있습니까?

+0

아시다시피 파이썬의 GIL 때문에 파이썬의 멀티 스레딩은 멀티 스레드처럼 보입니다.하지만 실제는 아닙니다. 파이썬으로 멀티 코어를 이용하려면 멀티 프로세싱을 사용해야합니다. 현대 컴퓨터에서 프로세스를 만들고 스레드를 만드는 데는 거의 같은 비용이 듭니다. – Yves

+0

스레드를 생성하는 것은 프로세스를 만드는 것과 비슷한 비용을 가질 수 있지만 스레드 간 통신은 프로세스간에 통신하는 데 비용이 많이 듭니다. (아마도 공유 메모리를 사용하지 않는 한). 또한 GIL에 대한 귀하의 의견은 부분적으로 만 사실입니다. I/O 작업 중 및 CPU 바인딩 작업 중에도 일부 라이브러리 (예 : numpy)에서 릴리스됩니다. 여전히 GIL은 궁극적으로 파이썬에서 별도의 프로세스를 사용하는 이유입니다. –

답변

5

multiprocessing.pool.ThreadPool은 작업자 논리를 실행하는 프로세스 대신 스레드를 사용하는 유일한 차이점을 가지고 multiprocessing.Pool과 동일하게 작동합니다.

이유는 당신은 multiprocessing.Pool 여러 번 인쇄되는

hi outside of main() 

볼 사실로 인해입니다 풀 것 spawn 5 독립적 인 프로세스 그. 자신의 파이썬 인터프리터를 초기화하고 모듈을로드하여 최상위 레벨 print이 다시 실행되는 각 프로세스.

이 경우는 spawn 프로세스 생성 방법이 사용 된 경우에만 발생합니다 (Windows에서만 사용할 수있는 방법). fork (Unix)을 사용하면 스레드에 대해 메시지가 한 번만 인쇄됩니다.

구현이 완료되지 않았으므로 multiprocessing.pool.ThreadPool은 문서화되어 있지 않습니다. 테스트와 문서가 부족합니다. source code에서 해당 구현을 볼 수 있습니다.

다음 자연스러운 질문은 스레드 기반 풀을 언제 사용하고 프로세스 기반 프로세스를 사용해야하는지 생각해보십시오.

엄지 손가락의 규칙은 다음과 같습니다

  • IO 바인딩 작업 ->multiprocessing.pool.ThreadPool
  • CPU 바인딩 작업 - multiprocessing.Pool
  • 하이브리드 채용 정보> -> 작업 부하에 따라, 나는 보통 multiprocessing.Pool 인해 선호 이점은 프로세스 분리가 발생합니다.

파이썬 3에서는 concurrent.future.Executor 풀 구현을 살펴볼 수 있습니다. .

+0

답해 주셔서 감사합니다. 이 문장을 이해하고 싶습니다. 이것은 생성 프로세스 생성 방법이 사용 된 경우에만 발생합니다 (Windows에서만 사용할 수있는 방법). 포크 1 (Unix)을 사용하면 스레드에 대해 메시지가 한 번만 인쇄됩니다. "map()"또는 "Pool()"을 호출 할 때 "스폰"및 "포크"가 암시 적이라고 가정합니다. 아니면 내가 통제 할 수있는 것인가? – ozn

+0

설명은 [스폰] (https://docs.python.org/3.6/library/multiprocessing.html#contexts-and-start-methods) 시작 메소드를 언급 할 때 위 링크에서 설명합니다. 이를 제어 할 수 있지만 시작 방법의 가용성은 OS 플랫폼에 따라 다릅니다. 기본 시작 전략은'spawn' 전략으로 Windows를 사용한다고 가정합니다. 그렇다면 Windows가'스폰 '만 지원하기 때문에 할 일이 거의 없습니다. – noxdafox