郭
←返回首页郭佳恩前端工程师
25 分钟阅读技术专栏
构建高性能 Rust 异步运行时
深入理解 Rust 的 async/await 机制。我们将探讨 Future trait 的工作原理,以及如何使用 Tokio 构建高并发网络服务。
RustBackendConcurrencySystems Programming
Rust 的异步模型是 "Zero-cost abstractions" 的典范。
1. Future Trait
Rust 的异步核心是 Future trait。它类似于 JavaScript 的 Promise,但是它是惰性的(Lazy)。
rustpub trait Future { type Output; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>; } pub enum Poll<T> { Ready(T), Pending, }
除非你通过 .await 或执行器(Executor)去轮询它,否则 Future 什么都不会做。
2. 使用 Tokio 构建 TCP Echo Server
Tokio 是 Rust 最流行的异步运行时。
rustuse tokio::net::TcpListener; use tokio::io::{AsyncReadExt, AsyncWriteExt}; #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> { let listener = TcpListener::bind("127.0.0.1:8080").await?; loop { let (mut socket, _) = listener.accept().await?; tokio::spawn(async move { let mut buf = [0; 1024]; // In a loop, read data from the socket and write the data back. loop { let n = match socket.read(&mut buf).await { // socket closed Ok(n) if n == 0 => return, Ok(n) => n, Err(e) => { eprintln!("failed to read from socket; err = {:?}", e); return; } }; // Write the data back if let Err(e) = socket.write_all(&buf[0..n]).await { eprintln!("failed to write to socket; err = {:?}", e); return; } } }); } }
3. 在线程间共享状态
使用 Arc 和 Mutex 在异步任务间安全地共享状态。
rustuse std::sync::Arc; use tokio::sync::Mutex; type Db = Arc<Mutex<HashMap<String, String>>>; #[tokio::main] async fn main() { let db: Db = Arc::new(Mutex::new(HashMap::new())); // ... pass db to handlers }