← [ BACK_TO_NOTES ]

Rust Send 与 Sync

Send/Sync 标记 trait 如何描述跨线程移动与共享;数据竞争防护在类型系统中的落点。

#concept #growing #dev #rust

[!info] related notes

Rust Send 与 Sync

这个概念为什么出现

“无数据竞争”不是靠文档约定,而是靠类型:

  • 哪些值可以移到别的线程?→ Send
  • 哪些值可以通过共享引用被多线程碰?→ Sync

自动推导与正确的类型约束能在编译期拒绝不满足条件的用法;错误的 unsafe impl 是作者违反安全契约,编译器不会替作者证明它正确。

[!abstract] 一句话理解 T: Send 表示所有权可安全转移到其他线程;T: Sync 表示 &T 可安全共享到其他线程(等价于 &T: Send)。

最小可运行示例

场景:把只读配置 Arc 分发给工作线程

配置在主线程构建,工作线程只读共享。Arc<String>: Send + Sync(String 满足 Send + Sync)允许这样做。

use std::sync::Arc;
use std::thread;

// 业务意图:多线程只读共享配置。
// 教学点:Arc 使共享所有权;Send/Sync 让编译通过。

fn main() {
    let cfg = Arc::new(String::from("mode=prod"));
    let mut handles = vec![];
    for i in 0..3 {
        let cfg = Arc::clone(&cfg);
        handles.push(thread::spawn(move || {
            println!("worker{i} cfg={cfg}");
        }));
    }
    for h in handles { h.join().unwrap(); }
}

建议运行:cargo run

期望:三个 worker 都打印同一配置(顺序不定)。

结合场景再看三个关注点

  1. Rc 不能这样跨线程(非线程安全计数)
  2. 共享可变需要 Mutex 等 才能让内部可变也安全
  3. marker trait 无方法,却约束整个并发生态

核心概念与准确模型

Trait含义(直觉)
Send可转移所有权到其他线程
Sync可共享引用到其他线程

关系直觉:T 是 Sync ⇔ &T 是 Send。

常见:

  • 绝大多数基础类型:Send + Sync
  • Rc:非 Send 非 Sync
  • RefCell<T> 在 T: Send 时为 Send,但不是 Sync;独占转移与共享引用是不同能力
  • std::sync::MutexGuard 不实现 Send;不要推广到其他库同名 guard
  • Arc 跨线程共享需要 T: Send + Sync;Mutex 的 Send/Sync 要求 T: Send,故 Arc<Mutex> 可保护 Send 但非 Sync 的 T

设计动机

  • 编译期消灭数据竞争类 bug
  • 不安全实现必须用 unsafe impl 并证明不变量
  • API 作者用 trait bound 表达线程契约

边界与误区

  • 自动 trait 规则有例外与条件实现
  • unsafe impl Send/Sync 是高风险
  • 满足 Send/Sync ≠ 无死锁

[!warning] 常见误区:Sync 就是“类型可变也随便共享” 共享可变仍需同步原语。

工程实践

  1. 根据独占转移、共享所有权或作用域借用选择接口;普通共享引用也可在 T: Sync 与寿命满足时安全跨线程
  2. 库文档写清线程安全
  3. 不要随手 unsafe impl
  4. 用编译器错误学习边界

本节总结

  • Send/Sync 是并发类型根基
  • 决定 Rc vs Arc、RefCell vs Mutex
  • 安全并发的编译期合同

自测题

  1. 为什么 Rc<T> 一般不能传入 thread::spawn?
  2. Arc<Mutex<T>> 解决了什么?
参考答案
  1. 非原子引用计数,不是 Send/Sync 安全组合。
  2. 多线程共享所有权 + 互斥访问内部 T。

延伸阅读与资料来源

资料类型支撑内容
The Book — Send and Sync官方书Send/Sync
std::marker::Send标准库Send
Nomicon — Send and Sync官方深层规则
创建于 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
关闭浮层 / 取消命令;输入框内清空文本