推理基础设施 · Python6.3 asyncio.create_task:把协程扔后台跑
06
asyncio 基础 · 3 / 5

6.3 asyncio.create_task:把协程扔后台跑

💡 推理服务里"日志上报"、"metrics 推送"都是后台任务

6.3 asyncio.create_task

立即启动协程,不阻塞当前流程

import asyncio

async def background_log(msg):
    await asyncio.sleep(0.5)
    print(f"[log] {msg}")

async def main():
    asyncio.create_task(background_log("hello"))   # 立刻返回,不等
    print("main 继续跑")
    await asyncio.sleep(1)                          # 让后台任务有机会完成

asyncio.run(main())

和 gather 的区别

  • gather:等所有任务完成
  • create_task:启动后立即返回,后面用 await task 单独等

推理服务里

  • create_task 用来启动“后台任务”(日志上报、metrics、心跳)
  • gather 用来并发等“主业务任务”

示范

import asyncio

async def report_metrics():
    await asyncio.sleep(0.1)
    print("[metrics] sent")

async def main():
    asyncio.create_task(report_metrics())
    print("main done before metrics?")
    await asyncio.sleep(0.2)   # 等后台任务跑完

asyncio.run(main())

✍️ 练习

  1. 写一个协程 report(label, latency_ms)await asyncio.sleep(latency_ms/1000)print(f"[{label}] sent")
  2. main 里:
    • 立刻 create_task 三个 report 调用:report("metrics", 100)report("log", 200)report("trace", 300)
    • print("main: tasks scheduled")
    • await asyncio.sleep(0.4) 等后台任务结束
    • print("main: done")

注意观察 print 顺序。

💡 思路提示

点开看提示
  1. create_task 返回 Task 对象,但不需要存它的变量
  2. 如果 main 立即结束,后台任务会被强制取消——所以要有 await 给它们机会跑完
  3. asyncio.sleep 在这里既是等后台,也是给事件循环机会调度

✅ 参考解法

写不出来再打开
import asyncio

async def report(label, latency_ms):
    await asyncio.sleep(latency_ms / 1000)
    print(f"[{label}] sent")

async def main():
    asyncio.create_task(report("metrics", 100))
    asyncio.create_task(report("log", 200))
    asyncio.create_task(report("trace", 300))
    print("main: tasks scheduled")
    await asyncio.sleep(0.4)
    print("main: done")

asyncio.run(main())

🔍 进阶思考

生产代码常用 asyncio.TaskGroup(Python 3.11+)来管理后台任务,比手 create_task 干净:

async with asyncio.TaskGroup() as tg:
    tg.create_task(report("metrics", 100))
    tg.create_task(report("log", 200))
# 退出 with 时自动 await 所有任务

异常也会被 TaskGroup 收集,不会“漏跑”。