【问题标题】:Python multiprocessing RuntimeErrorPython 多处理运行时错误
【发布时间】: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 的顶级调用,因此不会创建进程。

标签: python python-3.x python-2.7 multiprocessing python-multiprocessing


【解决方案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__ 是“ma​​in”,否则,__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),但它仍然抛出错误。
猜你喜欢
  • 2015-09-02
  • 2015-12-06
  • 2016-03-31
  • 2019-05-22
  • 2021-07-23
  • 1970-01-01
  • 2016-03-18
  • 2020-11-19
  • 2021-04-26
相关资源
最近更新 更多