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

在tokio::task中await Python协程时PyO3-asyncio无事件循环报错求助

解决Rust中tokio::spawn调用pyo3_asyncio时"no running event loop"错误

出现这个错误的核心原因是:tokio::spawn创建的新异步任务会在独立的执行上下文运行,原线程的Python事件循环并没有被自动关联到这个新任务中,导致pyo3_asyncio::into_future找不到可用的事件循环。

解决思路是手动将原Python事件循环的句柄传递到新任务,并在任务初始化时将其关联到当前tokio线程上下文,具体实现步骤如下:

1. 确保依赖配置正确

在Cargo.toml中添加正确的依赖及features,确保pyo3-asyncio与tokio集成:

[dependencies]
pyo3 = { version = "0.21", features = ["auto-initialize"] }
pyo3-asyncio = { version = "0.21", features = ["tokio-runtime"] }
tokio = { version = "1.0", features = ["full"] }

2. Rust侧实现代码

use pyo3::prelude::*;
use pyo3_asyncio::tokio::{get_current_loop, attach, into_future};
use tokio;

#[pyfunction]
async fn run_py_coroutine(py: Python, coro: &PyAny) -> PyResult<()> {
    // 获取当前线程关联的Python事件循环句柄
    let loop_handle = get_current_loop(py)?;

    // 将事件循环句柄移入tokio异步任务
    tokio::spawn(async move {
        // 在新任务中获取GIL(所有Python操作必须在GIL保护下进行)
        let py = Python::acquire_gil();
        
        // 将事件循环关联到当前tokio任务的上下文
        attach(py, &loop_handle).await?;

        // 转换Python协程为Rust Future并执行
        let future = into_future(coro)?;
        future.await?;

        Ok(()) as PyResult<()>
    }).await??; // 等待任务完成并处理嵌套的Result

    Ok(())
}

#[pymodule]
fn rust_async_ext(_py: Python, m: &PyModule) -> PyResult<()> {
    m.add_function(wrap_pyfunction!(run_py_coroutine, m)?)?;
    Ok(())
}

3. Python侧测试代码

import asyncio
import rust_async_ext

async def test_py_coro():
    print("Python协程开始执行")
    await asyncio.sleep(1.0)
    print("Python协程执行完成")

async def main():
    await rust_async_ext.run_py_coroutine(test_py_coro())

asyncio.run(main())

关键细节说明

  • get_current_loop:获取当前持有GIL的线程所关联的Python事件循环句柄,这个句柄可以安全地移动到其他tokio任务中。
  • attach:将传入的事件循环绑定到当前tokio任务的执行线程,确保后续pyo3-asyncio的API能找到正确的事件循环。
  • GIL获取:新任务中所有操作Python对象的步骤(包括attach和into_future)都必须在GIL保护下进行,因此需要调用Python::acquire_gil()。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 11:30:04