Rust异步编程入门指南
刚接触Rust的异步编程,想请教几个基础问题:1)Future和async/await的关系是什么?2)tokio和async-std这两个运行时该如何选择?3)在写异步代码时有哪些常见的性能陷阱需要注意?4)能否推荐一些适合初学者的异步编程实践项目?
2 回复
Rust异步编程入门:
- 使用
async/.await语法 - 依赖
tokio或async-std运行时 - 用
#[tokio::main]标记主函数 - 掌握
Futuretrait和任务调度 - 注意共享状态的线程安全(如
Arc<Mutex<T>>)
推荐官方《Async Book》和tokio文档练习。
Rust异步编程入门指南
异步编程允许程序在等待I/O操作时执行其他任务,提高资源利用率。Rust通过async/await语法和强大的运行时支持异步编程。
核心概念
1. async/await 基础
use std::time::Duration;
use tokio::time::sleep;
// 使用 async 定义异步函数
async fn fetch_data() -> String {
sleep(Duration::from_secs(1)).await; // 使用 .await 等待异步操作
"数据获取完成".to_string()
}
#[tokio::main]
async fn main() {
let result = fetch_data().await;
println!("{}", result);
}
2. Future trait
所有异步函数都返回实现了 Future trait 的类型:
use std::future::Future;
async fn process() -> i32 { 42 }
// 上面的函数等价于:
fn process() -> impl Future<Output = i32> {
async { 42 }
}
常用异步运行时
Tokio(最流行)
# Cargo.toml
[dependencies]
tokio = { version = "1.0", features = ["full"] }
async-std
[dependencies]
async-std = "1.12"
实际应用示例
并发执行多个任务
use tokio::time::{sleep, Duration};
async fn task_one() -> &'static str {
sleep(Duration::from_secs(2)).await;
"任务一完成"
}
async fn task_two() -> &'static str {
sleep(Duration::from_secs(1)).await;
"任务二完成"
}
#[tokio::main]
async fn main() {
// 使用 join! 并发执行
let (result1, result2) = tokio::join!(task_one(), task_two());
println!("{}, {}", result1, result2);
}
使用 select! 处理多个异步操作
use tokio::time::{sleep, Duration, timeout};
#[tokio::main]
async fn main() {
let slow_task = sleep(Duration::from_secs(5));
let timeout_duration = Duration::from_secs(3);
tokio::select! {
_ = slow_task => println!("任务完成"),
_ = sleep(timeout_duration) => println!("超时"),
}
}
异步通道通信
use tokio::sync::mpsc;
#[tokio::main]
async fn main() {
let (tx, mut rx) = mpsc::channel(32);
// 生产者任务
tokio::spawn(async move {
for i in 0..5 {
tx.send(i).await.unwrap();
tokio::time::sleep(Duration::from_millis(100)).await;
}
});
// 消费者
while let Some(message) = rx.recv().await {
println!("收到: {}", message);
}
}
最佳实践
- 避免在异步函数中执行阻塞操作
- 合理使用
.await,避免不必要的等待 - 使用
tokio::spawn创建新任务 - 注意生命周期和所有权问题
错误处理
async fn may_fail() -> Result<String, &'static str> {
// 模拟可能失败的操作
if true {
Ok("成功".to_string())
} else {
Err("失败")
}
}
#[tokio::main]
async fn main() {
match may_fail().await {
Ok(result) => println!("成功: {}", result),
Err(e) => println!("错误: {}", e),
}
}
这个指南涵盖了Rust异步编程的基础知识,建议从简单的异步函数开始,逐步学习更复杂的并发模式。

