asyncio代码同步执行问题:循环调用异步函数未实现并发如何解决
问题根因
你当前代码未实现异步并发的核心原因是:在async_io函数的循环中直接await main(i),await的语义是等待当前协程执行完成后才会继续执行后续代码,因此10个任务是串行排队执行的,总耗时约30秒,和同步版本没有差异。
解决方案
有两种常用的实现异步并发的写法,核心逻辑都是先将所有协程提交为事件循环的后台任务,再统一等待所有任务执行完成:
方案1:使用asyncio.gather批量执行
这是最简洁的批量并发执行协程的方式,修正后代码如下:
import time import asyncio async def main(x): print(f"Starting Task {x}") await asyncio.sleep(3) print(f"Finished Task {x}") async def async_io(): # 批量生成10个协程,交给gather并发执行 await asyncio.gather(*[main(i) for i in range(10)]) if __name__ == "__main__": start_time = time.perf_counter() asyncio.run(async_io()) print(f"Took {time.perf_counter() - start_time} secs")
运行后总耗时约3秒,符合异步并发的预期。
方案2:手动创建Task再批量等待
你提到的应该是asyncio.create_task方法,使用该方法也可以实现相同效果,示例如下:
async def async_io(): tasks = [] for i in range(10): # 先将协程包装为任务,提交到事件循环后台排队 task = asyncio.create_task(main(i)) tasks.append(task) # 统一等待所有任务执行完成 for task in tasks: await task
通用排查思路
- 首先检查所有阻塞操作是否替换为异步版本:你已经将
time.sleep替换为asyncio.sleep,这一步是正确的,如果混用同步阻塞API会直接导致异步失效 - 检查协程调用逻辑:直接对单个协程执行
await一定会触发串行执行,需要并发的场景必须先把协程注册为事件循环的任务 - 可以通过打印任务启动时间验证并发效果:如果所有任务的启动日志几乎同时输出,说明并发生效;如果是逐个输出启动日志,说明仍然是串行执行
内容的提问来源于stack exchange,提问作者meh
相关产品推荐
相关产品推荐

