如何在Python中让异步协程尽早启动实现eager执行?
解决方案
Python异步协程默认是懒执行的:直接调用异步函数返回的协程对象只有被
await时才会执行;用asyncio.create_task提交到事件循环后,也需要当前运行的协程主动让出CPU,任务才会被调度执行。你之前用await asyncio.sleep(0)的逻辑是对的,属于事件循环标准的主动让出操作,只是写法冗余,可以通过封装工具函数优化。
最简实现方案
封装通用的提前启动工具函数,一次调用即可让嵌套的所有协程都执行到第一个IO挂起点:
import asyncio from typing import Coroutine, Task async def early_start(coro: Coroutine) -> Task: # 先把协程包装成任务加入事件循环就绪队列 task = asyncio.create_task(coro) # 主动让出CPU,让事件循环调度所有就绪任务到首次IO阻塞 await asyncio.sleep(0) return task
改造后的业务代码:
async def subsubfunc(): print(" subsubfunc") # [some async I/O code here] 此处IO操作触发挂起,自动让出CPU async def subfunc(): print(" subfunc A") subsub_task = await early_start(subsubfunc()) print(" subfunc B") await subsub_task print(" subfunc C") async def func(): print("func A") sub_task = await early_start(subfunc()) print("func B") await sub_task print("func C") asyncio.run(func())
运行上述代码输出完全匹配你的期望,且不需要多次重复写await asyncio.sleep(0),嵌套层级再多也只需要每个子任务调用一次early_start即可。
适用场景说明
这个方案完美匹配你提到的「先发请求再做其他操作」的需求:
- 调用
early_start后,所有子协程会执行到IO请求发送完成、等待响应的挂起点,自动把CPU交还给调用方 - 调用方此时可以执行其他不需要等待响应的业务逻辑,最后再
await任务拿到返回结果即可
如果不想封装工具函数,也可以直接用asyncio.wait实现等价逻辑,语义上更偏向任务调度:
task = asyncio.create_task(subfunc()) # 等待0秒,仅让就绪的任务执行到挂起点就返回 await asyncio.wait([task], timeout=0)
内容的提问来源于stack exchange,提问作者Al Gebra
相关产品推荐
相关产品推荐

