← 中文资源

简体中文版本

Python 报 RuntimeError: event loop is already running

在嵌套调用 asyncio.run 或从同步上下文调用异步代码时,解决“事件循环已在运行”的错误。

阅读英文原文

症状

调用 asyncio.run 的代码崩溃并报 RuntimeError: asyncio.run() cannot be called from a running event loop,或 This event loop is already running。该故障在 notebook、异步 Web 处理器以及自管事件循环的框架中很常见,因为周边环境已在同一线程运行着循环。

诊断

用 grep 找出所有启动循环的位置;在已有循环的环境里改用 await 或创建任务;若同步代码必须调用异步代码,则用 asyncio.to_thread 把工作放到独立线程。

grep -rn "asyncio.run\|run_until_complete\|new_event_loop" .

根因

两个事件循环冲突。asyncio.run 会新建循环,而在同一线程已有循环运行时无法调用,因此嵌套创建循环才是缺陷根源。

修复

异步代码中直接 await 协程;同步代码在顶层只启动一次循环,或把阻塞工作放到独立线程中使用专属循环。坚持自启循环的库应从同步上下文调用或做相应包装。

验证

再次执行该路径确认不再报 RuntimeError,并检查协程的副作用或返回值,确保它确实执行而非被静默跳过。

常见陷阱

用 try/except 吞掉该异常会让协程根本没运行却看似成功;应修正循环结构而非掩盖错误。