← [ BACK_TO_NOTES ]

Rust 线程

std::thread 启动线程、move 闭包转移所有权、JoinHandle 等待与线程间基本协作入口。

#concept #growing #dev #rust

[!info] related notes

Rust 线程

这个概念为什么出现

CPU 密集或需要并行的工作会用到 OS 线程。
Rust 标准库提供 std::thread,并把“什么能跨线程移动”交给类型系统(Send)。

[!abstract] 一句话理解 thread::spawn 启动线程执行闭包(常用 move 捕获);通过 JoinHandle 等待结果;跨线程移动的数据必须满足 Send。

最小可运行示例

场景:报表服务并行汇总两个分区计数

夜间任务把两个分区的行数并行统计,主线程 join 后相加。

use std::thread;

// 业务意图:并行统计两个分区的记录数。
// 教学点:无捕获闭包无需 move;先 spawn 两个线程,再分别 join。

fn count_partition(name: &str, rows: u64) -> u64 {
    println!("counting {name}");
    rows // 示意
}

fn main() {
    let h1 = thread::spawn(|| count_partition("p1", 120));
    let h2 = thread::spawn(|| count_partition("p2", 80));
    let r1 = h1.join();
    let r2 = h2.join(); // 先等待两者,再检查各自结果
    let total = r1.expect("p1 panicked") + r2.expect("p2 panicked");
    println!("total_rows={total}");
}

建议运行:cargo run

期望输出(顺序可能交错):

counting p1
counting p2
total_rows=200

结合场景再看三个关注点

  1. join 处理线程 panic(Result)
  2. spawn 闭包与返回值均要求 Send + static;移动借用仍受原数据寿命限制,借用局部数据可用 thread::scope
  3. 线程不是 async 任务,更重

核心概念与准确模型

  • spawn → JoinHandle<T>
  • join 等待并取 Result<T>
  • 线程局部:thread_local!
  • Builder 可命名/设栈大小

与 channel/Mutex 组合才构成完整并发。

设计动机

  • 安全地暴露 OS 线程
  • 通过 Send 防数据竞争
  • 显式 join 表达生命周期

边界与误区

  • 无界创建线程可耗尽资源 → 线程池
  • 丢弃 JoinHandle 会分离线程,不会自动等待或取消;main 返回后进程可结束其他线程
  • join 的 Err 是线程 panic;若线程函数返回 Result,需区分 join 的外层错误与业务内层错误
  • thread::scope 在作用域退出前等待作用域线程,因此可借用栈数据;普通 spawn 不具有这一保证
  • 在 async 运行时里阻塞线程要谨慎

[!warning] 常见误区:在 async 函数里 thread::sleep 当并发 会阻塞工作线程;async 用定时器 future。

工程实践

  1. CPU 密集可考虑线程池
  2. I/O 密集优先 async 生态
  3. 命名线程便于排障
  4. 传播错误:join 后处理 panic 或返回值

本节总结

  • spawn/join 基础
  • move + Send
  • 与 channel/锁组合

自测题

  1. 为什么 spawn 的闭包常常要 move?
  2. join 返回 Err 通常表示?
参考答案
  1. 将非 Copy 的拥有数据转交线程;仍需满足 Send + static,move 一个短借用本身不够。
  2. 子线程 panic。

延伸阅读与资料来源

资料类型支撑内容
The Book — Fearless Concurrency官方书并发
std::thread标准库线程 API
创建于 2026/7/15 更新于 2026/10/7
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本