Python çoklu işlemeyi deneyen pencerelerde RuntimeError hatası


123

Bir Windows makinesinde Threading ve Multiprocessing kullanarak ilk resmi python programımı deniyorum. Yine de python aşağıdaki mesajı vererek işlemleri başlatamıyorum. Mesele şu ki, ana modülde konularımı başlatmıyorum . İş parçacıkları bir sınıf içinde ayrı bir modülde ele alınır.

DÜZENLEME : Bu arada, bu kod ubuntu'da iyi çalışıyor. Tam olarak pencerelerde değil

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.

Orijinal kodum oldukça uzun, ancak hatayı kodun kısaltılmış bir sürümünde yeniden oluşturabildim. İki dosyaya bölünmüştür, ilki ana modüldür ve süreçleri / iş parçacıkları işleyen ve bir yöntemi çağıran modülü içe aktarmaktan çok az şey yapar. İkinci modül, kodun etinin olduğu yerdir.


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

@doctorlove python olarak çalıştırıyorum testMain.py
NG Algo

1
Elbette - bir if ismine ihtiyacınız var == ' ana ' cevapları ve belgeleri görün
doctorlove

1
@NGAlgo Pymongo ve çoklu işlem ile ilgili bir problemde hata ayıklarken betiğiniz bana çok yardımcı oldu. Teşekkürler!
Clay

Yanıtlar:


175

Windows'ta alt işlemler başlangıçta ana modülü içe aktaracak (yani çalıştıracaktır). if __name__ == '__main__':Özyinelemeli alt işlemler oluşturmaktan kaçınmak için ana modüle bir koruma eklemeniz gerekir .

Değiştirildi testMain.py:

import parallelTestModule

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

3
(avucunu alnına vurur) Doh! İşe yarıyor!!!! Çok teşekkür ederim! Yeniden ithal edilen orijinal ana modül olduğu gerçeğini kaçırıyordum! Bunca zaman süreçlerimi başlattığım yerden hemen önce " name ==" kontrolünü deniyordum.
NG Algo

1
'ParallelTestModule' içe aktaramıyorum. Python 2.7 kullanıyorum. Kutudan çıkması gerekir mi?
Jonny

2
@Jonny parallelTestModule.py kodu sorunun bir parçasıdır.
Janne Karila

1
@DeshDeepSingh Kod parçacığı bağımsız bir örnek değildir; bu OP'nin kodunun bir değişikliğidir
Janne Karila

1
@DeshDeepSingh Bu modül sorunun bir parçasıdır.
Janne Karila

25

Kodunuzu testMain.py'deki bir ana işlevin içine koymayı deneyin

import parallelTestModule

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

Dokümanlara bakın :

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

hangisi diyor

"Ana modülün, istenmeyen yan etkilere neden olmadan (yeni bir işlemin başlatılması gibi) yeni bir Python yorumlayıcısı tarafından güvenli bir şekilde içe aktarılabileceğinden emin olun."

... kullanarak if __name__ == '__main__'


9

Önceki cevaplar doğru olsa da, üzerinde durmanın yardımcı olacağı küçük bir karmaşıklık var.

Ana modülünüzün, global değişkenlerin veya sınıf üyesi değişkenlerinin tanımlandığı ve bazı yeni nesneler için (veya kullanılarak) başlatıldığı başka bir modülü içe aktarması durumunda, içe aktarmayı aynı şekilde koşullandırmanız gerekebilir:

if __name__ ==  '__main__':
  import my_module

3

@Ofer'in dediği gibi, başka bir kitaplık veya modül kullanırken, hepsini if __name__ == '__main__':

Yani benim durumumda şöyle bitti:

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

0

Benim durumumda, kodda yaratılmadan önce değişken kullanan basit bir hataydı. Yukarıdaki çözümleri denemeden önce bunu kontrol etmeye değer. Neden bu özel hata mesajını aldım, Tanrı biliyor.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.