Trait core::marker::Sync 1.0.0[−][src]
pub unsafe auto trait Sync { }Expand description
可以在线程之间安全共享引用的类型。
当编译器确定适当时,会自动实现此 trait。
确切的定义是:当且仅当 &T 是 Send 时,类型 T 才是 Sync。
换句话说,如果在线程之间传递 &T 引用时没有 未定义的行为 (包括数据竞争) 的可能性。
正如人们所料,像 u8 和 f64 这样的原始类型都是 Sync,包含它们的简单聚合类型也是如此,比如元组、结构体和枚举。
基本 Sync 类型的更多示例包括不可变类型 (例如 &T) 以及具有简单继承的可变性的类型,例如 Box<T>,Vec<T> 和大多数其他集合类型。
(泛型参数必须为 Sync,才能使其容器为 [Sync]。)
该定义的一个令人惊讶的结果是 &mut T 是 Sync (如果 T 是 Sync),即使看起来可能提供了不同步的可变的。
诀窍是,共享引用 (即 & &mut T) 后面的可变引用将变为只读,就好像它是 & &T 一样。
因此,没有数据竞争的风险。
不是 Sync 的类型是具有非线程安全形式的 “内部可变性” 的类型,例如 Cell 和 RefCell。
这些类型甚至允许通过不可变,共享引用来更改其内容。
例如,Cell<T> 上的 set 方法采用 &self,因此它仅需要共享的引用 &Cell<T>。
该方法不执行同步,因此 Cell 不能为 Sync。
另一个非 Sync 类型的例子是引用计数指针 Rc。
给定任何引用 &Rc<T>,您可以克隆新的 Rc<T>,以非原子方式修改引用计数。
对于确实需要线程安全的内部可变性的情况,Rust 提供 原子数据类型 以及通过 sync::Mutex 和 sync::RwLock 进行的显式锁定。
这些类型可确保任何可变的都不会引起数据竞争,因此类型为 Sync。
同样,sync::Arc 提供了 Rc 的线程安全模拟。
任何具有内部可变性的类型还必须在值周围使用 cell::UnsafeCell 包装器,该包装器可以通过共享引用进行转变。
不这样做是 未定义的行为。
例如,从 &T 到 &mut T 的 transmute 无效。
有关 Sync 的更多详细信息,请参见 the Nomicon。
Implementors
NonNull 指针不是 Sync,因为它们引用的数据可能是别名。