Program Tip

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

programtip 2020. 10. 14. 20:50
반응형

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


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

On Windows the subprocesses will import (i.e. execute) the main module at start. You need to insert an if __name__ == '__main__': guard in the main module to avoid creating subprocesses recursively.

Modified testMain.py:

import parallelTestModule

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

Try putting your code inside a main function in testMain.py

import parallelTestModule

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

See the docs:

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

which say

"Make sure that the main module can be safely imported by a new Python interpreter without causing unintended side effects (such a starting a new process)."

... by using if __name__ == '__main__'


Though the earlier answers are correct, there's a small complication it would help to remark on.

In case your main module imports another module in which global variables or class member variables are defined and initialized to (or using) some new objects, you may have to condition that import in the same way:

if __name__ ==  '__main__':
  import my_module

참고URL : https://stackoverflow.com/questions/18204782/runtimeerror-on-windows-trying-python-multiprocessing

반응형