맨땅에 헤딩하는 사람

Windows 환경 ipython console에서 multiprocessing이 안되는 이유 본문

파이썬/이론

Windows 환경 ipython console에서 multiprocessing이 안되는 이유

purplechip 2020. 8. 9. 11:33

Python Spyder 사용 중 multiprocessing 관련해서 여러 문제가 생겨 정보를 찾아보던 중 "Multiprocessing in Python on Windows and Jupyter/Ipython — Making it work"라는 흥미로운 글을 발견해 참고하여 포스팅한다.

 

Windows 환경은 UNIX, Linux와 다르게 fork(부모프로세스가 자식프로세스를 생성하는 기능)를 지원하지 않는다. 이는 부모프로세스와 자식프로세스의 구분이 되지 않는다는 의미이며 이에 따라 windows 환경에서 python multiprocessing을 사용할 때 몇몇 제약이 생기게 된다. 간단한 예로 if __name__=='__main__' 구문이 없을 때 Linux에서는 스크립트가 정상작동하지만 윈도우에서는 에러가 발생한다. 이 글에서는 interactive shell을 사용하는 Jupyter, Spyder, IPython에서 multiprocessing.Pool()이 동작하지 않는 이유와 해결방법을 기술하겠다.

 

파이썬 multiprocessing 공식 문서에 보면 multiprocessing.Pool()에 다음과 같은 참고사항이 있다.

참고
이 패키지 내의 기능을 사용하려면 __main__ 모듈을 자식이 임포트 할 수 있어야 합니다. 이것은 프로그래밍 지침에서 다루지만, 여기에서 지적할 가치가 있습니다. 이것은 몇몇 예제, 가령 multiprocessing.pool.Pool 예제가 대화형 인터프리터에서 동작하지 않음을 의미합니다.

위에서 확인했듯이 windows는 자식프로세스를 구분할 수 없다. 따라서 아래와 같은 코드는 Linux에서는 실행되지만 Windows에서는 에러가 발생한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#import Pool
from multiprocessing import Pool
#Define a worker — a function which will be executed in parallel
def worker(x):
    return x*x
 
if __name__=='__main__':    
    #Assuming you want to use 3 processors
    num_processors = 3
    #Create a pool of processors
    p=Pool(processes = num_processors)
    #get them to work in parallel
    output = p.map(worker,[i for i in range(0,3)])
    print(output)
cs

겉으로 보기에는 아무 문제가 없어보이는 코드지만 실제로 interactive shell에서 실행시켜보면 프로세스는 동작을 멈추고 종료되지 않는다. 아마 __main__모듈을 import하지 못해 worker()함수를 사용하지 못하는 문제로 추정된다.  이를 해결하기 위해서는 함수부를 별도의 파이썬 파일로 생성해야 한다. 위에 있는 하나의 코드를 workers.pymain.py로 구분한다. 아래 코드는 구분된 코드들이다.

1
2
3
# workers.py
def worker(x):
    return x*x
cs

 

1
2
3
4
5
6
7
8
# main.py
from multiprocessing import Pool
import workers
if __name__ ==  '__main__'
    num_processors = 3
    p=Pool(processes = num_processors)
    output = p.map(workers.worker,[i for i in range(0,3)])
    print(output)
cs

위와 같은 방법을 사용하면 해결이 되지만 interactive shell에서 multiprocessing을 사용하는 것은 개인적으로 추천하지 않는다. 그 이유는 크게 두 가지인데 첫 번째는 위와 같은 이유로 파이썬 파일을 추가적으로 생성하는 것이 부담스럽고 두 번째로 interactive shell에서는 자식프로세스의 stdout이 부모프로세스에서 출력되지 않는다는 점이다. 이는 자식프로세스에 에러가 발생했을 때 추가적으로 알아내야하는 부분을 작성해야 하는 번거로움을 낳는다.

 

물론 출력하는 방법은 찾으면 나올 수도 있겠지만 간단하게 interacitve shell을 안쓰면 해결되는 문제이다. 내 경우도 spyder를 사용해 개발하던 중 multiprocess를 사용해야 할 상황이 발생하여 편집기 자체를 PyCharm으로 옮기게 되었다.

 

참고

"Multiprocessing in Python on Windows and Jupyter/Ipython — Making it work"

medium.com/@grvsinghal/speed-up-your-python-code-using-multiprocessing-on-windows-and-jupyter-or-ipython-2714b49d6fac

windows에서 python multiprocessing 사용 시 if __name__='__main__' 넣어야 하는 이유

stackoverflow.com/questions/20222534/python-multiprocessing-on-windows-if-name-main

pool이 ipython에서 안되는 이유

stackoverflow.com/questions/23641475/multiprocessing-working-in-python-but-not-in-ipython/23641560#23641560

python multiprocessing doc

docs.python.org/ko/3/library/multiprocessing.html

Comments