Rust语言

关注公众号 jb51net

关闭
首页 > 软件编程 > Rust语言 > rust异步编程

Rust异步编程实战指南

作者:liuxs1998

这篇用Tokio官方mini-redis客户端示例,逐行解释async/await如何连接Redis、设置和读取键值,还讲清了Tokio运行时背后的非阻塞机制,看代码怎么让任务在等待时让出CPU,适合高并发I/O场景,感兴趣的朋友一起看看吧

Rust异步编程主要靠async/await 语法‌和‌异步运行时‌来写非阻塞代码,核心是把任务表示成 Future,再由运行时(如 Tokio)去驱动执行,它适合高并发 I/O 场景,比如网络服务、文件读写、消息处理等。

#[tokio::main]
async fn main() -> Result<()> {
    // Open a connection to the mini-redis address.
    let mut client = client::connect("127.0.0.1:6379").await?;
    // Set the key "hello" with value "world"
    client.set("hello", "world".into()).await?;
    // Get key "hello"
    let result = client.get("hello").await?;
    println!("got value from the server; result={:?}", result);
    Ok(())
}

这段代码是 Tokio 官方教程 mini-redis 的客户端示例,演示了用 async/await 连接 Redis 服务、设置和读取键值对。

📜 逐行解析

#[tokio::main]
async fn main() -> Result<()> {

#[tokio::main]:这是属性宏,把 async fn main 转换成 Tokio 运行时的入口。展开后相当于:

fn main() {
    tokio::runtime::Runtime::new().unwrap().block_on(async {
        // 你的 async main 代码
    });
}

它负责创建 Tokio 运行时、启动执行器、阻塞等待 main Future 完成。

-> Result<()>:main 返回 Result,这样可以用 ? 传播错误。这里的 Result 通常是 anyhow::Result 或 std::io::Result。如果返回 Err,程序会以非零状态码退出并打印错误。

let mut client = client::connect("127.0.0.1:6379").await?;
client.set("hello", "world".into()).await?;
let result = client.get("hello").await?;
println!("got value from the server; result={:?}", result);

🔍 背后的运行时机制

这段代码能跑起来,靠的是 Tokio 运行时在背后做这些事:

  1. #[tokio::main] 创建运行时,把 main 作为第一个 Future 交给执行器。
  2. client::connect(...).await 发起 TCP 连接。连接没建立时返回 Pending,执行器去跑其他任务。连接建立后,epoll 事件唤醒任务,继续执行。
  3. client.set(...).await 发送请求并等待响应。等待期间任务挂起,不阻塞线程。
  4. client.get(...).await 同理。

整个过程中,当前线程没有被阻塞。如果同时有多个客户端任务,它们会在同一个线程上协作式交替执行。

🆚 对比:同步版本长什么样

如果用同步阻塞的方式写,代码会是这样:

fn main() -> Result<()> {
    let mut client = std::net::TcpStream::connect("127.0.0.1:6379")?;
    client.write_all(b"SET hello world\r\n")?;
    let mut buf = [0u8; 1024];
    let n = client.read(&mut buf)?;
    println!("got value: {:?}", &buf[..n]);
    Ok(())
}

区别在于:同步版本在 connect、write、read 时线程被挂起,什么都干不了。异步版本在等待时让出 CPU,执行器可以跑其他任务。

📌 一句话总结

这段代码用 #[tokio::main] 启动 Tokio 运行时,通过 .await 异步地连接 Redis、设置和读取键值。每个 .await 点都是任务让出 CPU 的时机,等待期间线程不阻塞,执行器可以调度其他任务。这就是异步非阻塞的典型写法。

到此这篇关于Rust异步编程实战指南的文章就介绍到这了,更多相关rust异步编程内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文