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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 10:15:05