使用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
相关产品推荐
相关产品推荐

