组合使用loop.run_until_complete与asyncio.gather触发RuntimeError:事件循环已运行
问题原因
错误的核心是嵌套调用事件循环运行逻辑:
asyncio.run(main())会自动创建一个新的事件循环,并将main异步函数提交到该循环中运行,此时循环已经处于运行状态- 你在
main函数内部又调用了asyncio.get_event_loop().run_until_complete(),尝试让已经在运行的事件循环再次启动执行新的任务,这是Python asyncio明确禁止的操作,所以抛出RuntimeError: This event loop is already running - 该问题和Python 3.9版本无关,之前能正常运行大概率是之前的入口代码没有使用
asyncio.run,而是直接在同步代码段调用run_until_complete,不存在嵌套启动循环的情况。
修复方案
最简单的修复方式是直接在main异步函数中await asyncio.gather返回的任务对象即可,不需要再手动调用事件循环的运行方法:
import asyncio async def count(label, number): for i in range(number): print(label, i) await asyncio.sleep(1) async def main(): # 直接await gather的结果即可,不需要手动操作事件循环 await asyncio.gather(count("a", 3), count("b", 5)) asyncio.run(main())
如果你习惯手动管理事件循环的写法,也可以去掉asyncio.run,直接在同步入口调用事件循环方法:
import asyncio async def count(label, number): for i in range(number): print(label, i) await asyncio.sleep(1) async def main(): await asyncio.gather(count("a", 3), count("b", 5)) if __name__ == "__main__": loop = asyncio.get_event_loop() loop.run_until_complete(main()) loop.close()
两种写法都可以实现两个异步函数并行运行的效果,总运行时间约5秒,符合预期。
内容的提问来源于stack exchange,提问作者finefoot
相关产品推荐
相关产品推荐

