Python 다중 처리를 시도하는 Windows의 RuntimeError


123

Windows 시스템에서 Threading 및 Multiprocessing을 사용하는 첫 번째 공식 파이썬 프로그램을 시도하고 있습니다. 그래도 파이썬이 다음 메시지를 표시하면서 프로세스를 시작할 수 없습니다. 문제는 메인 모듈 에서 내 스레드를 시작하지 않는다는 것입니다 . 스레드는 클래스 내의 별도 모듈에서 처리됩니다.

편집 : 그건 그렇고이 코드는 우분투에서 잘 실행됩니다. 창문에는별로

RuntimeError: 
            Attempt to start a new process before the current process
            has finished its bootstrapping phase.
            This probably means that you are on Windows and you have
            forgotten to use the proper idiom in the main module:
                if __name__ == '__main__':
                    freeze_support()
                    ...
            The "freeze_support()" line can be omitted if the program
            is not going to be frozen to produce a Windows executable.

내 원래 코드는 꽤 길지만 코드의 요약 버전에서 오류를 재현 할 수있었습니다. 두 개의 파일로 나뉘어져 있는데, 첫 번째는 메인 모듈이며 프로세스 / 스레드를 처리하고 메서드를 호출하는 모듈을 가져 오는 것 외에는 거의 수행하지 않습니다. 두 번째 모듈은 코드의 핵심입니다.


testMain.py :

import parallelTestModule

extractor = parallelTestModule.ParallelExtractor()
extractor.runInParallel(numProcesses=2, numThreads=4)

parallelTestModule.py :

import multiprocessing
from multiprocessing import Process
import threading

class ThreadRunner(threading.Thread):
    """ This class represents a single instance of a running thread"""
    def __init__(self, name):
        threading.Thread.__init__(self)
        self.name = name
    def run(self):
        print self.name,'\n'

class ProcessRunner:
    """ This class represents a single instance of a running process """
    def runp(self, pid, numThreads):
        mythreads = []
        for tid in range(numThreads):
            name = "Proc-"+str(pid)+"-Thread-"+str(tid)
            th = ThreadRunner(name)
            mythreads.append(th) 
        for i in mythreads:
            i.start()
        for i in mythreads:
            i.join()

class ParallelExtractor:    
    def runInParallel(self, numProcesses, numThreads):
        myprocs = []
        prunner = ProcessRunner()
        for pid in range(numProcesses):
            pr = Process(target=prunner.runp, args=(pid, numThreads)) 
            myprocs.append(pr) 
#        if __name__ == 'parallelTestModule':    #This didnt work
#        if __name__ == '__main__':              #This obviously doesnt work
#        multiprocessing.freeze_support()        #added after seeing error to no avail
        for i in myprocs:
            i.start()

        for i in myprocs:
            i.join()

내가 파이썬 testMain.py로 실행 @doctorlove
NG 너 한테에게

1
물론 - 당신은 만약 필요 이름 == ' '에 대한 답변과 문서 참조
doctorlove

1
@NGAlgo pymongo 및 다중 처리 문제를 디버깅하는 동안 스크립트가 매우 유용했습니다. 감사!
클레이

답변:


175

Windows에서 하위 프로세스는 시작시 기본 모듈을 가져옵니다 (즉, 실행). if __name__ == '__main__':하위 프로세스를 재귀 적으로 생성하지 않으려면 기본 모듈에 가드 를 삽입해야합니다 .

수정 testMain.py:

import parallelTestModule

if __name__ == '__main__':    
    extractor = parallelTestModule.ParallelExtractor()
    extractor.runInParallel(numProcesses=2, numThreads=4)

3
(손바닥을 이마에 대고)도! 효과가있다!!!! 정말 고맙습니다! 다시 가져 오는 것이 원래 메인 모듈이라는 사실을 놓쳤습니다! 이번에는 프로세스를 시작하기 직전에 " name =="확인을 시도 했습니다.
NG 너 한테

1
'parallelTestModule'을 가져올 수 없습니다. Python 2.7을 사용하고 있습니다. 상자에서 꺼내야할까요?
Jonny

2
@Jonny parallelTestModule.py의 코드는 질문의 일부입니다.
Janne Karila

1
@DeshDeepSingh 코드 조각은 독립 실행 형 예제가 아닙니다. 이는 영업 이익의 코드의 수정이다
의 Janne Karila

1
@DeshDeepSingh 그 모듈은 질문의 일부입니다.
Janne Karila

25

testMain.py의 주 함수 안에 코드를 넣어보십시오.

import parallelTestModule

if __name__ ==  '__main__':
  extractor = parallelTestModule.ParallelExtractor()
  extractor.runInParallel(numProcesses=2, numThreads=4)

문서 참조 :

"For an explanation of why (on Windows) the if __name__ == '__main__' 
part is necessary, see Programming guidelines."

어느 말

"의도하지 않은 부작용 (예 : 새 프로세스 시작)을 일으키지 않고 새 Python 인터프리터가 주 모듈을 안전하게 가져올 수 있는지 확인하십시오."

... 사용하여 if __name__ == '__main__'


9

이전 답변이 정확하지만 언급하는 데 도움이되는 작은 문제가 있습니다.

기본 모듈이 전역 변수 또는 클래스 멤버 변수가 정의되고 일부 새 개체로 초기화 (또는 사용)되는 다른 모듈을 가져 오는 경우 동일한 방식으로 가져 오기를 조건화해야 할 수 있습니다.

if __name__ ==  '__main__':
  import my_module

3

@Ofer가 말했듯이 다른 라이브러리 나 모듈을 사용할 때는 모든 라이브러리를 if __name__ == '__main__':

그래서 제 경우에는 다음과 같이 끝났습니다.

if __name__ == '__main__':       
    import librosa
    import os
    import pandas as pd
    run_my_program()

0

제 경우에는 생성되기 전에 변수를 사용하는 코드의 간단한 버그였습니다. 위의 해결책을 시도하기 전에 확인해 볼 가치가 있습니다. 내가이 특별한 오류 메시지를받은 이유는 주님 께서 알고 계십니다.

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