Python 多处理运行时错误
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()
大多数在线帖子都这样建议 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()
执行导入 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()
我有一个简单的函数,我打算使用 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()
大多数在线帖子都这样建议 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()
执行导入 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()