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

协程并发实现原理解析:await与asyncio.gather的适用场景

两种异步测试场景的运行机制解析及await vs asyncio.gather的使用时机

先看你代码里的核心问题:asleep函数虽然用async定义,但内部调用的是time.sleep(n)——这是同步阻塞的IO操作,它会直接卡住整个Python线程,不让事件循环有机会切换到其他协程。这是理解两个场景差异的关键前提。

场景1:await asleep(2)(无并发)

当事件循环启动后,会按顺序调度任务:

  1. 先执行doAsync1,打印doAsync1 start...,然后走到await asleep(2)。
  2. 进入asleep后,time.sleep(2)直接阻塞线程,事件循环完全被卡住,根本没机会切换到doAsync2或doAsync3。
  3. 2秒后阻塞结束,doAsync1打印doAsync1 end...并完成。
  4. 事件循环才会调度下一个任务doAsync2,重复上述步骤,直到三个任务全部完成。

最终呈现串行执行的效果,总耗时6秒——这不是await本身的问题,是因为asleep里的阻塞操作让协程根本没机会挂起释放事件循环。

场景2:await asyncio.gather(asleep(2))(伪并发)

这里的关键是asyncio.gather的行为:它会把传入的可等待对象注册到事件循环,然后当前协程主动挂起,让事件循环去调度其他就绪的任务:

  1. 事件循环先调度doAsync1,打印doAsync1 start...,执行到await asyncio.gather(asleep(2))时,doAsync1挂起,事件循环切换到doAsync2。
  2. doAsync2打印doAsync2 start...,同样执行到await gather(...)时挂起,事件循环切换到doAsync3。
  3. doAsync3打印doAsync3 start...,执行到await gather(...)时挂起。
  4. 此时所有任务都处于等待状态,事件循环会唤醒第一个等待的任务(比如doAsync1),执行asleep(2)里的time.sleep(2),再次阻塞线程2秒。
  5. 阻塞结束后doAsync1完成,事件循环唤醒doAsync2,执行它的time.sleep(2),再阻塞2秒;接着是doAsync3的2秒阻塞。
  6. 最后三个任务依次完成,打印各自的end...。

你看到的“三个start同时输出”,是因为asyncio.gather让每个doAsync任务在遇到await时主动挂起,给了其他任务执行的机会。但因为time.sleep的阻塞特性,实际的asleep操作还是串行的,总耗时还是6秒——如果把time.sleep(n)换成异步的await asyncio.sleep(n),那三个asleep(2)会真的并发执行,总耗时就变成2秒了。

什么时候用await some_work(),什么时候用await asyncio.gather(...)

用await some_work()的场景

  • 你需要按顺序执行单个协程,当前任务的后续代码依赖这个协程的执行结果或状态。比如:
    async def fetch_user_data(user_id):
        data = await get_user_from_db(user_id)  # 必须拿到数据才能继续处理
        await update_user_profile(data)
    
  • 处理单个异步操作,不需要并发执行其他任务时。

用await asyncio.gather(...)的场景

  • 你有多个独立的异步任务,它们之间没有依赖关系,可以同时执行来提升效率。比如同时请求多个第三方API:
    async def fetch_multiple_data():
        tasks = [fetch_api(url1), fetch_api(url2), fetch_api(url3)]
        results = await asyncio.gather(*tasks)  # 三个请求并发执行,总耗时等于最慢的那个请求
        process_results(results)
    
  • 需要等待一组异步任务全部完成后,再统一处理结果时。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:48:04