簡體   English   中英

Python 多處理運行時錯誤

[英]Python multiprocessing RuntimeError

我有一個簡單的 function 打算使用 Python 多處理模塊並行運行。 但是我收到以下錯誤RuntimeError: An attempt has been made to start a new process before the current process has finished its bootstrapping phase. 該錯誤表明我添加了這個:

if __name__ == '__main__':
freeze_support()

並且大多數在線帖子都建議與此 SO answer相同。

我添加了它並且它可以工作,但我似乎不明白為什么這么簡單的一段代碼需要它。

沒有 __name__=="__main__" 的代碼(拋出 RuntimeError)

import multiprocessing
import time

start = time.perf_counter()


def do_something():
    print('Sleeping 1 second...')
    time.sleep(1)
    print('Done sleeping...')

p1 = multiprocessing.Process(target=do_something)
p2 = multiprocessing.Process(target=do_something)
p1.start()
p2.start()

finish = time.perf_counter()

print(f'Finished in {round(finish - start, 2)} second(s)')

帶有 __name__=="__main__" 的代碼(不拋出 RuntimeError)

import multiprocessing
import time

start = time.perf_counter()


def do_something():
  print('Sleeping 1 second...')
  time.sleep(1)
  print('Done sleeping...')


def main():
   p1 = multiprocessing.Process(target=do_something)
   p2 = multiprocessing.Process(target=do_something)
   p1.start()
   p2.start()

   finish = time.perf_counter()
   print(f'Finished in {round(finish - start, 2)} second(s)')


if __name__ == "__main__":
   main()

在 Windows 中, multiprocessing.Process執行 python 的新副本以運行代碼。 它必須獲取您要執行的代碼以在該進程中加載,以便它挑選您當前環境的快照以在子進程中擴展。 為此,孩子需要重新導入父母使用的模塊。 特別是,它需要將主腳本作為模塊導入。 導入時,駐留在模塊級別的任何代碼都會執行。

所以讓我們做一個最簡單的案例

foo.py

import multiprocessing as mp
process = mp.Process(target=print, args=('foo',))
process.start()
process.join()

process.start()執行一個新的 python 導入foo.py 這就是問題所在。 新的foo將創建另一個子進程,該子進程將再次導入 foo.py。 於是創建了一個進程。

除非 python 檢測到問題並引發異常,否則 go 將一直打開,直到您炸毀您的機器。

修復

Python 模塊具有__name__屬性。 如果您將程序作為腳本運行, __name__是“ main ”,否則, __name__是您的模塊的名稱。 因此,當一個多處理進程正在導入您的主腳本來設置您的環境時,它的名稱不是__main__ 您可以使用它來確保您的 MP 工作僅在父模塊中完成。

import multiprocessing as mp

if __name__ == "__main__":
    # run as top level script, but not as imported module
    process = mp.Process(target=print, args=('foo',))
    process.start()
    process.join()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM