RuntimeError trên cửa sổ đang thử xử lý đa quy trình python


122

Tôi đang thử chương trình python chính thức đầu tiên của mình bằng cách sử dụng Phân luồng và Đa xử lý trên máy windows. Tuy nhiên, tôi không thể khởi chạy các quy trình với python đưa ra thông báo sau. Vấn đề là, tôi không khởi chạy các chủ đề của mình trong mô-đun chính . Các luồng được xử lý trong một mô-đun riêng biệt bên trong một lớp.

CHỈNH SỬA : Bằng cách này, mã này chạy tốt trên ubuntu. Không hoàn toàn trên windows

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.

Mã gốc của tôi khá dài, nhưng tôi đã có thể tạo lại lỗi trong một phiên bản rút gọn của mã. Nó được chia thành hai tệp, tệp đầu tiên là mô-đun chính và thực hiện rất ít công việc ngoài việc nhập mô-đun xử lý các quy trình / luồng và gọi một phương thức. Mô-đun thứ hai là nơi chứa thịt của mã.


testMain.py:

import parallelTestModule

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

song songTestModule.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 Tôi chạy nó dưới dạng python testMain.py
NG Algo

1
Chắc chắn - bạn cần một nếu tên == ' chính ' thấy câu trả lời và các tài liệu
doctorlove

1
@NGAlgo Tập lệnh của bạn rất hữu ích với tôi khi tôi đang gỡ lỗi sự cố với pymongo và đa xử lý. Cảm ơn!
Clay

Câu trả lời:


173

Trên Windows, các quy trình con sẽ nhập (tức là thực thi) mô-đun chính khi bắt đầu. Bạn cần chèn một bộ if __name__ == '__main__':bảo vệ trong mô-đun chính để tránh tạo các quy trình con một cách đệ quy.

Đã sửa đổi testMain.py:

import parallelTestModule

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

3
(đập lòng bàn tay vào trán) Doh! Nó hoạt động !!!! Cảm ơn bạn rất nhiều! Tôi đã thiếu thực tế rằng nó là mô-đun chính ban đầu được nhập lại! Tất cả thời gian này, tôi đã thử kiểm tra " tên ==" ngay trước khi tôi khởi chạy các quy trình của mình.
NG Algo

1
Tôi dường như không thể nhập'llelTestModule '. Tôi đang sử dụng Python 2.7. Nó có nên hoạt động ra khỏi hộp không?
Jonny

2
@Jonny Mã chollelTestModule.py là một phần của câu hỏi.
Janne Karila

1
@DeshDeepSingh Đoạn mã không phải là một ví dụ độc lập; nó là một sự sửa đổi mã OP của
Janne Karila

1
@DeshDeepSingh Mô-đun đó là một phần của câu hỏi.
Janne Karila 20/07/18

25

Hãy thử đặt mã của bạn bên trong một hàm chính trong testMain.py

import parallelTestModule

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

Xem tài liệu :

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

mà nói

"Đảm bảo rằng mô-đun chính có thể được nhập một cách an toàn bằng trình thông dịch Python mới mà không gây ra các tác dụng phụ không mong muốn (chẳng hạn như bắt đầu một quy trình mới)."

... bằng cách sử dụng if __name__ == '__main__'


9

Mặc dù các câu trả lời trước đây là đúng, nhưng có một sự phức tạp nhỏ mà bạn cần nhận xét.

Trong trường hợp mô-đun chính của bạn nhập một mô-đun khác trong đó các biến toàn cục hoặc biến thành viên lớp được xác định và khởi tạo cho (hoặc sử dụng) một số đối tượng mới, bạn có thể phải điều kiện nhập theo cùng một cách:

if __name__ ==  '__main__':
  import my_module

3

Như @Ofer đã nói, khi bạn đang sử dụng các thư viện hoặc mô-đun khác, bạn nên nhập tất cả chúng vào bên trong if __name__ == '__main__':

Vì vậy, trong trường hợp của tôi, đã kết thúc như thế này:

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

0

Trong trường hợp của tôi, đó là một lỗi đơn giản trong mã, sử dụng một biến trước khi nó được tạo. Đáng kiểm tra điều đó trước khi thử các giải pháp trên. Tại sao tôi nhận được thông báo lỗi cụ thể này, Chúa biết.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.