python - 为什么 multiprocessing.Process 在这里不起作用?
问题描述
我正在 jupyter notebook 和 spyder 上测试多处理:
import multiprocessing
import time
start = time.perf_counter()
def do_something():
print(f'Sleeping 5 second(s)...')
time.sleep(5)
print(f'Done Sleeping...')
p2 = multiprocessing.Process(target = do_something)
p3 = multiprocessing.Process(target = do_something)
p2.start()
p3.start()
p2.join()
p3.join()
finish = time.perf_counter()
print(f'Finished in {round(finish-start, 2)} secounds')
我得到了:
Finished in 0.12 secounds
这比 5 秒短得多。我确实测试了 do_something 函数,它看起来不错。我觉得在上面的代码中,do_someting 函数甚至没有执行......
start = time.perf_counter()
def do_something(seconds):
print(f'Sleeping {seconds} second(s)...')
time.sleep(seconds)
print(f'Done Sleeping...{seconds}')
do_something(5)
finish = time.perf_counter()
print(f'Finished in {round(finish-start, 2)} secounds')
Sleeping 5 second(s)...
Done Sleeping...5
Finished in 5.0 secounds
解决方案
你的代码应该抛出一个错误(我不会写回溯来保持答案简短):
RuntimeError:
An attempt has been made to start a new process before the
current process has finished its bootstrapping phase.
This probably means that you are not using fork to start your
child processes and you have forgotten to use the proper idiom
in the main module:
if __name__ == '__main__':
freeze_support()
...
The "freeze_support()" line can be omitted if the program
is not going to be frozen to produce an executable.
长话短说:多处理包无法正确理解和执行您的代码。您应该将定义保留在文件的开头,并将要执行的代码放在
if __name__ == '__main__':
否则,每个新进程都将尝试执行相同的文件(并产生其他进程)。在我的电脑上完成更正的代码大约需要 5.22 秒。
在 multiprocessing 包的编程指南(“安全导入主模块”部分)中解释了“if”的需要。请务必阅读它们以避免不必要的行为:多线程和多处理在不正确使用时容易出现难以捉摸的错误。
这是更正后的代码:
import multiprocessing
import time
def do_something():
print('Sleeping 5 seconds...')
time.sleep(5)
print('Done Sleeping.')
if __name__ == '__main__':
start = time.perf_counter()
p2 = multiprocessing.Process(target=do_something, args=())
p3 = multiprocessing.Process(target=do_something, args=())
p2.start()
p3.start()
p2.join()
p3.join()
finish = time.perf_counter()
print(f'Finished in {round(finish-start, 2)} seconds')
为什么你会在 0.12 秒后看到输出?发生这种情况是因为每个子进程都会抛出错误并崩溃(您应该得到两个相同的运行时错误),然后父进程才能完成。
推荐阅读
- amazon-web-services - 如何为 Yii2 安装/使用 AWS:ElastiCache Redis 会话
- javascript - 如何解决 discord.js 中的 await 问题?
- java - 使用 ModelMapper 转换实体
- git - 所有分支的 Git 拉取
- amazon-redshift - AWS Redshift 集群表 vs 频谱,选择什么
- arrays - 打字稿:类型“数字”不能用作索引类型
- python-3.x - Gtk - Pixbuf.new_from_stream_at_scale_async 正在阻塞 UI
- sql - 如何检查动态列名是否为空
- javascript - 传单:如何将多边形与 GeoJson 合并?使用 Javascript
- reactjs - i18n 与 React - 如何为特定语言环境创建 .json 文件?