You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:00:36