Python multiprocessing RuntimeError



>我有一个简单的函数,我打算使用 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()

大多数在线帖子都建议与这个答案相同。

我添加了它并且它可以工作,但我似乎不明白为什么这么简单的代码段需要它。

没有 __name__=="__main__" 的代码(抛出运行时错误)

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__" 的代码(不会引发运行时错误)

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 检测到问题并引发异常。

修复

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

相关内容

  • 没有找到相关文章

最新更新