Python 多处理运行时错误
Posted
技术标签:
【中文标题】Python 多处理运行时错误【英文标题】:Python multiprocessing RuntimeError 【发布时间】:2020-09-19 09:53:51 【问题描述】:我有一个简单的函数,我打算使用 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()
【问题讨论】:
你在第一个脚本中有缩进吗?do_something
创建一个调用do_something
等的进程,这会很快爆炸,除非没有对do_something
的***调用,因此不会创建进程。
可能相关:bugs.python.org/issue37205
【参考方案1】:
在 Windows 中,multiprocessing.Process
执行一个新的 python 副本来运行代码。它必须获取您要执行的代码以在该进程中加载,以便它挑选当前环境的快照以在子进程中扩展。为此,孩子需要重新导入父母使用的模块。特别是,它需要将主脚本作为模块导入。导入时,驻留在模块级别的任何代码都会执行。
让我们做一个最简单的例子
foo.py
import multiprocessing as mp
process = mp.Process(target=print, args=('foo',))
process.start()
process.join()
process.start()
执行一个导入foo.py
的新python。这就是问题所在。新的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()
【讨论】:
感谢您的详细回答。但是,我使用的是 Mac OS (Mojave),但它仍然抛出错误。以上是关于Python 多处理运行时错误的主要内容,如果未能解决你的问题,请参考以下文章
Python - 运行多个使用多处理的 python 脚本有时会影响性能和错误