直接回答Send 表示值的所有权可以安全转移到另一个线程;Sync 表示值的引用可以在多线程间共享(即 &T 是 Send)。它们是 auto trait,编译器按结构自动推导:所有字段 Send 则整体 Send。Rc 既不 Send 也不 Sync,因为它的引用计数是非原子的普通整数,两个线程同时 clone 会数据竞争。需要跨线程共享就用 Arc——原子计数换来 Send + Sync,代价是每次 clone 有原子操作开销。

展开解析:这两个标记是 Rust 无数据竞争的基石:std::thread::spawn 要求闭包 Send,从类型层面保证跨线程移动的东西没有共享可变状态。几个对照记忆点:Cell/RefCell 是 Send(整个移走没问题)但不 Sync(多线程共享引用会同时触发非原子内部可变性);裸指针不 Send 不 Sync,逼迫 unsafe 代码显式声明责任。手动 unsafe impl 常见于 FFI 封装和自定义并发结构,声明前必须论证内部同步正确性——这是 unsafe 评审的重点。static mut 不 Sync,所以全局可变状态要包 Mutex 或用 OnceLock

追问方向:为什么 Mutex 是 Sync 而 T 只需 Send?Box 的 Send 性取决于什么?写 unsafe 封装时如何论证 Send/Sync?

(约 430 字)