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())
✍️ 练习
- 写一个协程
report(label, latency_ms):await asyncio.sleep(latency_ms/1000),print(f"[{label}] sent") 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 顺序。
💡 思路提示
点开看提示
create_task返回 Task 对象,但不需要存它的变量- 如果 main 立即结束,后台任务会被强制取消——所以要有
await给它们机会跑完 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 收集,不会“漏跑”。