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

使用asyncio.gather未实现任务并发执行,求排查问题

问题原因及解决办法

你的代码存在问题,核心错误是使用了同步阻塞的sleep(10),而非asyncio提供的异步睡眠方法asyncio.sleep(10)。

为什么会出现串行输出?

asyncio的协程并发依赖于事件循环的切换:只有当协程遇到可等待对象(比如异步IO、asyncio.sleep这类不阻塞线程的操作)时,事件循环才会暂停当前协程,转而执行其他等待中的协程。

而普通的sleep(10)是直接阻塞整个线程的——一旦某个协程执行到这行代码,整个事件循环都会被卡住,必须等10秒睡眠结束,这个协程打印完***2***后,才会轮到下一个协程启动,最终就出现了串行的输出结果。

修正后的代码

把同步sleep替换为异步的asyncio.sleep,同时优化协程的创建方式:

import asyncio
# 假设exchange_list是已定义的目标列表
exchange_list = ["exchange1", "exchange2", "exchange3"]

async def main():    
    # gather可以直接接收协程对象,无需手动调用ensure_future
    order_book_coroutines = [get_order_book_list() for exchange in exchange_list]
    results = await asyncio.gather(*order_book_coroutines)

async def get_order_book_list():
    print('***1***')
    await asyncio.sleep(10)  # 替换为异步睡眠
    try:
       # 执行API查询(注意要使用异步HTTP库,比如aiohttp,避免同步阻塞)
       pass
    except Exception as e:
        pass
    print('***2***')

if __name__ == "__main__":
    asyncio.run(main())

修正后效果

运行后会先一次性打印三个***1***,等待10秒后,再一次性打印三个***2***,完全符合你的预期输出。

另外补充:你对asyncio.gather的功能理解是正确的——它确实用于并发启动多个协程,无需等待前一个完成就启动下一个,但前提是协程内部的操作是异步非阻塞的,否则会破坏并发逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 02:55:40