Skip to content
Souloss
Go back

Rust 并发编程实战

Rust 系列第四篇:探索 Rust 的并发编程能力,包括线程、消息传递、共享状态以及 async/await 异步编程模型。

教程/Rust |
| 2 分钟阅读 | 487 字

Rust 的并发安全保证

Rust 有一个著名的口号:「无畏并发」(Fearless Concurrency)。得益于所有权系统和类型系统,Rust 在编译时就能排除绝大部分并发错误,如数据竞争。

线程基础

创建线程

使用 move 闭包

当需要在线程间传递数据所有权时:

use std::thread;

fn main() {
    let data = vec![1, 2, 3, 4, 5];

    let handle = thread::spawn(move || {
        let sum: i32 = data.iter().sum();
        println!("数据总和: {}", sum);
        sum
    });

    // data 已移动,此处无法再使用
    let result = handle.join().unwrap();
    println!("线程返回: {}", result);
}
rust

消息传递

Rust 标准库提供了 mpsc(多生产者,单消费者)通道来实现线程间通信:

共享状态

Mutex(互斥锁)

RwLock(读写锁)

当读操作远多于写操作时,RwLockMutex 更高效:

Async/Await 异步编程

对于 I/O 密集型任务,Rust 的 async/await 模型比线程更加高效:

基础异步函数

use tokio; // 最常用的异步运行时

async fn fetch_data(url: &str) -> Result<String, reqwest::Error> {
    let response = reqwest::get(url).await?;
    let body = response.text().await?;
    Ok(body)
}

#[tokio::main]
async fn main() {
    match fetch_data("https://api.example.com/data").await {
        Ok(data) => println!("获取到数据: {} bytes", data.len()),
        Err(e) => eprintln!("请求失败: {}", e),
    }
}
rust

并发执行多个任务

使用 Stream 处理异步数据流

use tokio_stream::StreamExt;

async fn process_stream() {
    let mut stream = tokio_stream::iter(vec![1, 2, 3, 4, 5])
        .map(|x| x * 2)
        .filter(|x| *x > 4);

    while let Some(value) = stream.next().await {
        println!("流数据: {}", value);
    }
}
rust

实战:并发 Web 爬虫

以下是一个综合运用并发概念的简单爬虫示例:

Send 和 Sync Trait

Rust 的并发安全靠两个标记 trait 来保证:

绝大多数类型自动实现了这两个 trait。如果你使用了不满足这些约束的类型(如 Rc<T>),编译器会在编译时报错,阻止你写出有数据竞争的代码。

小结

Rust 的并发编程模型是其最强大的特性之一。无论你使用线程、消息传递还是异步编程,编译器都会在背后守护你的代码安全。这就是「无畏并发」的真正含义——你可以放心大胆地编写并发代码,因为编译器已经帮你排除了绝大部分隐患。

上一篇Rust 错误处理最佳实践

恭喜你完成了「从零开始学 Rust」系列! 现在你已经掌握了 Rust 最核心的四大概念。继续实践,多写项目,你会越来越感受到 Rust 的魅力。



上一篇
Rust 错误处理最佳实践

相关推荐

评论区

文明评论,共建和谐社区