掌握Tokio异步运行时的核心概念:任务、调度器、IO驱动和定时器。
// Cargo.toml
[dependencies]
tokio = { version = "1", features = ["full"] }
// 最简Tokio程序
#[tokio::main]
async fn main() {
println!("Hello from Tokio!");
}
// 等价于
fn main() {
tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.unwrap()
.block_on(async {
println!("Hello from Tokio!");
})
}
✅ 编译验证通过
use tokio::time::{sleep, Duration};
#[tokio::main]
async fn main() {
// spawn创建并发任务
let handle = tokio::spawn(async {
sleep(Duration::from_millis(100)).await;
"任务完成"
});
// 等待任务
let result = handle.await.unwrap();
println!("结果: {}", result);
// 多任务并发
let mut handles = vec![];
for i in 0..5 {
handles.push(tokio::spawn(async move {
sleep(Duration::from_millis(50 * i as u64)).await;
i * i
}));
}
for h in handles {
println!("结果: {}", h.await.unwrap());
}
}
✅ 编译验证通过
// 多线程运行时(默认)
#[tokio::main]
async fn main() { }
// 单线程运行时(轻量级)
#[tokio::main(flavor = "current_thread")]
async fn main() { }
// 自定义工作线程数
#[tokio::main(worker_threads = 4)]
async fn main() { }
// 手动构建
let rt = tokio::runtime::Builder::new_multi_thread()
.worker_threads(4)
.thread_stack_size(2 * 1024 * 1024)
.enable_all()
.build()
.unwrap();
| 组件 | 功能 |
|---|---|
| tokio::net | 异步TCP/UDP/Unix |
| tokio::fs | 异步文件IO |
| tokio::time | 定时器和延时 |
| tokio::sync | 异步同步原语 |
| tokio::io | AsyncRead/AsyncWrite |
| tokio::signal | 信号处理 |
use tokio::sync::{Mutex, Semaphore, broadcast, mpsc};
#[tokio::main]
async fn main() {
// 异步Mutex(跨.await持有)
let data = Mutex::new(0);
{
let mut lock = data.lock().await;
*lock += 1;
}
// 信号量(限制并发数)
let sem = Semaphore::new(3); // 最多3个并发
let permit = sem.acquire().await.unwrap();
// 广播通道
let (tx, mut rx1) = broadcast::channel(16);
let mut rx2 = tx.subscribe();
// mpsc通道
let (tx, mut rx) = mpsc::channel(32);
}
用Semaphore实现API调用速率限制。
实现Ctrl+C信号处理和优雅关闭。
用tokio::sync::mpsc实现异步生产者消费者。
掌握Tokio——Rust异步生态的核心
Rust的异步模型与其他语言有本质区别:
async函数不是语法糖生成闭包或Future对象,而是编译器生成一个状态机enum,每个.await点是一个状态。这比Green Thread更高效——无堆分配、无运行时开销。
不使用的异步特性不产生代码。不调用async函数?没有状态机代码。这与其他语言的全局运行时(Go的goroutine调度器、Java的Fiber)不同。
Rust没有内置异步运行时。你选择Tokio、async-std或其他——运行时是库,不是语言特性。这意味着灵活但需要选择。
| 模型 | 语言 | 开销 | 并发数 |
|---|---|---|---|
| OS线程 | C/Java | 1-8MB/线程 | ~1000 |
| Green Thread | Go | ~2KB/goroutine | ~100K |
| async/await | Rust | ~几百字节 | ~1M+ |
| 回调 | Node.js | 小 | 高 |
以下资源帮助你深入学习本课主题:
本课涉及的核心概念,确保你理解每一个:
| 术语 | 说明 |
|---|---|
| 所有权 | Rust内存管理的核心机制,每个值有唯一所有者 |
| 借用 | 通过引用访问数据,不获取所有权 |
| 生命周期 | 引用有效的范围,编译期分析工具 |
| trait | Rust的接口/抽象机制,类似其他语言的接口 |
| 泛型 | 参数化类型,零成本抽象 |
| 模式匹配 | 强大的数据解构和分支机制 |
| 零成本抽象 | 高层抽象不引入运行时开销 |
| fearless concurrency | 编译器保证线程安全 |
Q: Rust学习曲线真的很陡吗?
A: 前期确实需要适应所有权和借用检查器,但一旦理解了,这些概念会让你的代码更可靠。大多数人2-4周就能上手。
Q: Rust适合什么项目?
A: 系统编程、Web服务、CLI工具、嵌入式、WASM、网络服务、数据库等。基本上需要性能和安全的地方都适合。
Q: 遇到编译错误怎么办?
A: Rust编译器的错误信息非常友好!仔细阅读,通常会指出问题所在和修复建议。也可以用cargo clippy获取更多提示。