Python asyncio.gather执行完所有任务后未退出的问题如何解决?
问题根因
你调用asyncio.all_tasks()获取所有任务时,当前正在运行的foo1协程自身对应的任务也包含在返回的任务集合中。你调用await asyncio.gather(*pending)等于要求等待foo1自己执行完成,但是foo1此时已经阻塞在这行await语句上,形成了永久等待的死锁逻辑,所以永远不会执行后续的print("done")。
修复方案
只需要把当前foo1自身的任务从等待集合中排除即可,修改foo1的代码如下:
async def foo1(): t = asyncio.create_task(foo2()) # 排除当前正在运行的foo1自身任务 pending = asyncio.all_tasks() - {asyncio.current_task()} await asyncio.gather(*pending)
修改后运行代码,所有foo2、foo3任务执行完成后,gather就会正常返回,最终输出done。
可选的更规范实现
如果不想依赖all_tasks()这种全局获取任务的方式(嵌套层级复杂时更容易控制任务生命周期),可以主动收集子任务:
async def foo2(): tasks = [] for x in range(2): await asyncio.sleep(0.5) task = asyncio.create_task(foo3(x)) tasks.append(task) print(f"foo2 {x}") # 返回所有创建的foo3任务,供上层等待 return tasks async def foo1(): t = asyncio.create_task(foo2()) foo3_tasks = await t await asyncio.gather(*foo3_tasks)
这种方式不需要全局获取任务,逻辑更清晰可控,也不会出现误等自身任务的问题。
内容的提问来源于stack exchange,提问作者kav
相关产品推荐
相关产品推荐

