首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Rust 多线程编程教程:从基础到实战,解锁并发神力!

Rust 多线程编程教程:从基础到实战,解锁并发神力!

作者头像
不吃草的牛德
发布2026-04-23 11:48:31
发布2026-04-23 11:48:31
1030
举报
文章被收录于专栏:RustRust

在单核时代,线程是奢侈品;如今多核 CPU 遍地,线程是标配。但是并发编程的坑太多——数据竞争、死锁、内存泄漏……Rust 以其“零成本抽象”和铁腕借用检查器,化险为夷,让你写出安全、高效的多线程代码。

1. Rust 线程基础:spawn、join 和 move 闭包Rust 的线程在 std::thread 模块中。最简单的方式:用 thread::spawn 创建线程,返回一个 JoinHandle,用 join 等待结果。入门代码:Hello World 多线程版

代码语言:javascript
复制
use std::thread;
use std::time::Duration;
fn main() {
    // 创建一个线程,打印消息
    let handle = thread::spawn(|| {
        for i in 1..=5 {
            println!("线程 {}: 嗨,从线程来!", i);
            thread::sleep(Duration::from_millis(100));  // 模拟工作
        }
    });
    // 主线程也干活
    for i in 1..=3 {
        println!("主线程 {}: 我在忙呢!", i);
        thread::sleep(Duration::from_millis(200));
    }
    // 等待子线程结束
    handle.join().unwrap();
    println!("所有线程完成!");
}

运行后,你会看到主线程和子线程交替输出。spawn 的闭包必须是 FnOnce,因为线程启动后就“消费”了它。如果闭包捕获外部变量,默认借用会报错(线程生命周期独立),所以用 move 关键字移动所有权。小 tip:join 阻塞主线程,直到子线程结束。忽略它,程序可能提前退出。2. 实际案例一:并行计算斐波那契数列斐波那契(Fib)是经典递归问题,单线程慢如狗。用线程并行计算大 Fib 值,性能飞起!场景:批量计算 Fib(30)、Fib(31)、Fib(32)单线程版太慢,我们用线程池(std::thread 内置)并行。

代码语言:javascript
复制
use std::thread;
fn fib(n: u64) -> u64 {
    if n <= 1 { n } else { fib(n-1) + fib(n-2) }  // 简单递归,实际用 memoization
}
fn main() {
    let handles: Vec<_> = (30..=32)
        .map(|n| {
            thread::spawn(move || {  // move 捕获 n
                let res = fib(n);
                println!("Fib({}) = {}", n, res);
                res
            })
        })
        .collect();
    for handle in handles {
        let result = handle.join().unwrap();
        println!("线程返回: {}", result);
    }
}

输出类似:

代码语言:javascript
复制
Fib(30) = 832040
Fib(31) = 1346269
Fib(32) = 2178309
线程返回: 832040
...

为什么会快?因为 每个线程独立计算,不共享状态。实际项目中,用 rayon 库(Cargo add rayon)简化:let results: Vec<_> = (30..=32).into_par_iter().map(fib).collect(); —— 零 boilerplate!性能对比:单线程 ~5s,多线程 ~2s(视 CPU 核数)。在数据科学工具中,这能加速矩阵运算或模拟。3. 线程通信:通道(Channels)入门线程间不共享数据?用 std::sync::mpsc(multiple producer, single consumer)通道传递消息。像邮局:发送方 sender,接收方 receiver。案例:生产者-消费者模式模拟日志系统:主线程生产日志,子线程消费并打印。

代码语言:javascript
复制
use std::sync::mpsc;
use std::thread;
use std::time::Duration;
fn main() {
    let (tx, rx) = mpsc::channel();  // 创建通道
    // 生产者线程
    let producer = thread::spawn(move || {
        for i in 1..=5 {
            let log = format!("日志 {}: 系统正常", i);
            tx.send(log).unwrap();  // 发送消息
            thread::sleep(Duration::from_millis(200));
        }
    });
    // 消费者(主线程)
    for received in rx {  // 阻塞接收,直到通道关闭
        println!("收到: {}", received);
        if received.contains("5") { break; }
    }
    producer.join().unwrap();
}

输出:

代码语言:javascript
复制
收到: 日志 1: 系统正常
收到: 日志 2: 系统正常
...

扩展:多生产者用 mpsc::sync_channel。在 Web 爬虫中,线程抓取页面,主线程汇总结果,避免阻塞。4. 共享数据:Arc + Mutex 安全访问Rust 不允许直接共享可变数据(防数据竞争)。用 Arc(原子引用计数)共享所有权,Mutex(互斥锁)保护访问。实际案例:多线程计数器银行转账模拟:多个线程并发存款,共享余额。

代码语言:javascript
复制
use std::sync::{Arc, Mutex};
use std::thread;
fn main() {
    let counter = Arc::new(Mutex::new(0));  // 共享可变计数器
    let mut handles = vec![];
    for _ in 0..10 {  // 10 个线程各加 100
        let counter = Arc::clone(&counter);  // 克隆 Arc
        let handle = thread::spawn(move || {
            let mut num = counter.lock().unwrap();  // 加锁
            *num += 100;
        });
        handles.push(handle);
    }
    for handle in handles {
        handle.join().unwrap();
    }
    println!("最终余额: {}", *counter.lock().unwrap());  // 1000
}

为什么安全?Mutex::lock 确保同一时间只有一个线程修改。Arc 管理引用计数,线程结束自动释放。

实战场景:在游戏服务器中,Arc<Mutex<Player>> 共享玩家状态;或 CLI 工具并行下载文件,Mutex 记录进度条。警告:死锁风险!别在锁内调用另一个锁住的 Mutex。用 RwLock 优化读多写少场景。5. 高级技巧与常见坑

  • 线程池:std::thread 适合简单任务,用 rayon 或 tokio(异步)处理复杂并发。
  • 错误处理:join 返回 Result,用 ? 传播 panic。
  • 坑一:忘记 move,借用跨线程报错。
  • 坑二:无限 join 循环,程序挂起——用 select!(futures 库)超时。
  • 性能:线程创建开销 ~1μs,多用池。基准测试用 criterion 库。

调试神器:RUST_LOG=debug cargo run,或 gdb 附着。线程,让 Rust 并发如丝般顺滑

Rust 线程不是“可选糖衣”,而是安全并发的基石。从 spawn 一个简单任务,到 Arc 守护共享状态,你已掌握 80% 技能。实战中,从小项目起步:试试并行排序日志文件,或构建 mini Web 服务器。Rust 的并发哲学:让编译器抓错,别让运行时崩溃。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-10-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Rust火箭工坊 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档