如何用asyncio.gather同时执行协程?遇事件循环已运行错误求助
解决RuntimeError: This event loop is already running问题
嘿,这个问题我之前在Jupyter环境里写异步代码时也踩过坑!你遇到的错误是因为当前环境中已经有一个异步事件循环在运行了,而你又试图用asyncio.get_event_loop().run_until_complete()再次启动循环,这就导致了冲突。
下面根据不同场景给你对应的解决方法:
常见场景及解决方法
场景1:你已经在一个运行中的事件循环环境里(比如Jupyter Notebook、GUI框架或其他异步框架)
这种情况下,不要尝试再启动新的循环,而是把你的协程提交到已有的循环中:
import asyncio async def _compare(max_bid, min_ask): if max_bid > min_ask: print('example') # 把你的逻辑包装成一个主协程 async def main(): await asyncio.gather( _compare(a_max_bid, b_min_ask), _compare(b_max_bid, a_min_ask) ) # 提交任务到已有的事件循环 asyncio.create_task(main())
如果你的代码本身就在一个异步函数里,那更简单,直接await即可:
# 假设这段代码在另一个async函数内部 await asyncio.gather( _compare(a_max_bid, b_min_ask), _compare(b_max_bid, a_min_ask) )
场景2:你在写独立的Python脚本
这种情况下,推荐使用Python 3.7+提供的asyncio.run(),它会自动帮你创建、运行和关闭事件循环,避免重复启动的问题:
import asyncio async def _compare(max_bid, min_ask): if max_bid > min_ask: print('example') async def main(): await asyncio.gather( _compare(a_max_bid, b_min_ask), _compare(b_max_bid, a_min_ask) ) if __name__ == "__main__": asyncio.run(main()) # 只启动一次循环,全程由它管理
如果你用的是Python 3.6及以下版本,那要确保只调用一次run_until_complete:
if __name__ == "__main__": loop = asyncio.get_event_loop() try: loop.run_until_complete(main()) finally: loop.close()
为什么会报错?
asyncio的事件循环是单线程的,同一时间只能有一个循环在运行。当你调用run_until_complete()时,它会阻塞当前线程直到协程完成,但如果此时已经有一个循环在运行(比如Jupyter默认会启动一个循环),就会抛出这个RuntimeError。
内容的提问来源于stack exchange,提问作者xulin tan
相关产品推荐
相关产品推荐

