为何使用ProcessPool时asyncio出现阻塞问题?附代码示例
使用ProcessPool时asyncio未执行完成的原因及修复方案
嘿,我来帮你搞定这个问题——你的代码差了最关键的一步,还有个小细节要注意,咱们拆解来看:
核心问题:事件循环没被启动到完成
你代码最后一行的loop...明显没写完,asyncio的事件循环不会自己跑起来,你必须明确告诉它要运行你的main协程直到结束。如果缺了这一步,协程只是被创建了,但事件循环根本没调度它执行,自然看不到后续的print("after process pool")和结果输出。
额外注意:ProcessPool的跨平台小坑
在Windows系统下,ProcessPoolExecutor依赖多进程的spawn机制,所以所有涉及创建进程的代码必须放在if __name__ == "__main__":块里,避免子进程重复执行顶层代码——这点你已经做对了,值得表扬,但还是提一下防止以后踩坑。
修复后的完整代码
我把代码改成了Python3.5+推荐的async/await语法(比旧的yield from更直观),补上了关键的事件循环启动代码:
import time import asyncio from concurrent.futures import ProcessPoolExecutor def blocking_func(x): print("In blocking waiting") time.sleep(x) # 模拟耗时计算 print("after blocking waiting") return x * 5 async def main(): executor = ProcessPoolExecutor() out = await loop.run_in_executor(executor, blocking_func, 2) print("after process pool") print(out) if __name__ == "__main__": loop = asyncio.get_event_loop() # 关键:让事件循环运行直到main协程执行完毕 loop.run_until_complete(main()) # 可选:关闭事件循环清理资源 loop.close()
更简洁的写法(Python3.7+)
如果你用的是Python3.7及以上版本,可以用asyncio.run()替代手动创建和管理事件循环,代码会更简洁:
if __name__ == "__main__": asyncio.run(main())
额外提醒
blocking_func必须是可以被序列化的函数(不能是嵌套函数、lambda或者带不可序列化属性的对象),否则ProcessPool在传递函数到子进程时会报错。
内容的提问来源于stack exchange,提问作者aja
相关产品推荐
相关产品推荐

