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

为何未使用await时asyncio.create_task创建的任务仍会执行?

关于asyncio.create_task()执行时机的疑问解答

通常资料提到asyncio.create_task(c)会“立即”运行协程c,区别于直接调用协程必须await才执行。但实际任务要执行到第一个await才会被调度启动,不过测试发现完全不使用await时,程序结束前创建的任务仍会执行第一步,以下是示例代码及输出:

示例代码

import asyncio

async def counter_loop(x, n):
    for i in range(1, n + 1):
        print(f"Counter {x}: {i}")
        await asyncio.sleep(0.5)
    return f"Finished {x} in {n}"


async def main():
    slow_task = asyncio.create_task(counter_loop("Slow", 4))
    fast_coro = asyncio.create_task(counter_loop("Fast", 2))
    print("Created tasks")
    for _ in range(1000):
        pass
    print("main ended")

asyncio.run(main())
print("program ended")

输出结果

Created tasks
main ended
Counter Slow: 1
Counter Fast: 1
program ended

原因解释

这个现象和asyncio事件循环的shutdown阶段行为直接相关:

  1. 调用asyncio.create_task时,协程会被包装成任务加入事件循环的任务队列,但不会立刻打断当前运行的main协程——main会继续执行直到自身结束。
  2. 当main协程执行完毕,asyncio.run()会触发事件循环进入shutdown流程。此时事件循环会调度所有已提交但未完成的任务,让它们运行到第一个await暂停点,或者任务完成。
  3. 你的counter_loop协程中,第一个print语句在await asyncio.sleep(0.5)之前,所以任务会先执行这个print,随后遇到await暂停。但事件循环处于shutdown阶段,不会等待任务恢复执行,直接终止循环。
  4. 最后事件循环退出,程序执行print("program ended")。

如果希望任务完全执行完毕,需要在main中显式await创建的任务,比如在print("main ended")前添加await slow_task和await fast_coro,这样事件循环会等待任务完成后再进入shutdown。

内容的提问来源于stack exchange,提问作者user118967

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 18:52:10