python multiprocessing child process not running on Windows

이 글은 내가 Windows에서 python multiprocessing 라이브러리 사용 도중 직면한 오류와 그 해결 방법을 다룬다.

오류

import time, os

from multiprocessing import Process

  

def work_func(x):

    print("value %s is in PID : %s" % (x, os.getpid()))

    return x**5

  

def main():

    start = int(time.time())

    procs = []    

    for num in range(1,11):

        proc = Process(target=work_func, args=(num,))

        procs.append(proc)

        proc.start()

        print(proc.is_alive())

    time.sleep(5)

    for proc in procs:

        proc.join()

        print(proc.is_alive())

    print("***run time(sec) :", int(time.time()) - start)

  

print("!")

if __name__ == "__main__":

    main()

exit()

위 스크립트를 윈도우에서 실행했을 때 work_func의 PID가 전혀 출력되지 않음
WSL에서 실행했을 때 정상 실행됨

def main에서 time sleep을 걸어둬도 작업관리자에 프로세스가 하나밖에 안 뜨는 걸 보고 혹시 child process 자체가 생성되지 않는건가 생각했으나, 그건 아니었음(단지 실행되자마자 종료되었을 뿐)

원인

Windows에서 multiprocrssing은 리눅스와 달리 새로운 프로세스를 spawning하는 방식으로 동작함
이는 원래 자신의 소스코드를 import한후 함수를 호출하는 형식으로 추정됨
따라서 Linux와 달리 Windows에서 multiprocessing 라이브러리를 사용하려면 ifmain 설정이 필요불가결하고, 내가 올린 위 스크립트처럼 exit() 구문이 마지막에 있으면 import 도중 exit이 실행되며 프로세스가 꺼져버림. PID를 출력하기 전에.

따라서 exit() 구문만 지우면 정상실행된다.

Q. exit()을 도대체 왜 넣었나요?
A. 그 뒤에 실행하지 않고 싶었던 소스코드를 잠깐 넣어뒀었거든요. 그냥 주석처리했으면 이런 삽질도 안했을텐데..

삽질

물론 이걸 내가 처음부터 알았던 건 아니고, 윈도우에서는 실행이 안되는데 WSL에서는 실행이 잘되고 소스코드에는 아무런 문제가 없어 보이는 상황에 직면해 멘붕이 왔었음
Python을 3.7에서 3.9로 올려보고, anaconda python 대신 native python으로 돌려보고, 소스코드도 multiprocrring의 process 말고 pool 등을 이용하는 것으로 바꿔봤으나 아무 진전이 없었음

자고 일어나서 다시 보니 도대체 어떻게 짐작했는지 모르겠는데 문득 exit()이 문제인 것 같아 지워 봤더니 잘 됨

ㅎㅎ; 이것 때문에 몇 시간 정도 날린 것 같다.