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
的类型是具有非线程安全形式的 “interior mutability” 的类型,例如 Cell
和 RefCell
。
这些类型甚至允许通过不可变,共享引用来更改其内容。
例如,Cell<T>
上的 set
方法采用 &self
,因此它仅需要共享的引用 &Cell<T>
。
该方法不执行同步,因此 Cell
不能为 Sync
。
另一个非 Sync
类型的例子是引用计数指针 Rc
。
给定任何引用 &Rc<T>
,您可以克隆新的 Rc<T>
,以非原子方式修改引用计数。
对于确实需要线程安全的内部可变性的情况,Rust 提供 atomic data types 以及通过 sync::Mutex
和 sync::RwLock
进行的显式锁定。
这些类型可确保任何可变的都不会引起数据竞争,因此类型为 Sync
。
同样,sync::Arc
提供了 Rc
的线程安全模拟。
任何具有内部可变性的类型还必须在 value(s) 周围使用 cell::UnsafeCell
包装器,该包装器可以通过共享的引用进行更改。
未定义的行为 无法做到这一点。
例如,从 &T
到 &mut T
的 transmute
无效。
有关 Sync
的更多详细信息,请参见 the Nomicon。
NonNull
指针不是 Sync
,因为它们引用的数据可能是别名的。
impl<'a, A> Sync for std::option::Iter<'a, A> where
A: Sync,
impl<'a, K> Sync for std::collections::hash_set::Drain<'a, K> where
K: Sync,
impl<'a, K> Sync for std::collections::hash_set::Iter<'a, K> where
K: Sync,
impl<'a, K, V> Sync for std::collections::btree_map::Entry<'a, K, V> where
K: Sync,
V: Sync,
impl<'a, K, V> Sync for std::collections::hash_map::Entry<'a, K, V> where
K: Sync,
V: Sync,
impl<'a, K, V> Sync for std::collections::btree_map::Iter<'a, K, V> where
K: Sync,
V: Sync,
impl<'a, K, V> Sync for std::collections::btree_map::Keys<'a, K, V> where
K: Sync,
V: Sync,
impl<'a, K, V> Sync for std::collections::btree_map::Range<'a, K, V> where
K: Sync,
V: Sync,
impl<'a, K, V> Sync for std::collections::btree_map::Values<'a, K, V> where
K: Sync,
V: Sync,
impl<'a, K, V> Sync for std::collections::hash_map::Drain<'a, K, V> where
K: Sync,
V: Sync,
impl<'a, K, V> Sync for std::collections::hash_map::Iter<'a, K, V> where
K: Sync,
V: Sync,
impl<'a, K, V> Sync for std::collections::hash_map::Keys<'a, K, V> where
K: Sync,
V: Sync,
impl<'a, K, V> Sync for std::collections::hash_map::Values<'a, K, V> where
K: Sync,
V: Sync,
impl<'a, T> !Sync for std::sync::mpsc::Iter<'a, T>
impl<'a, T> Sync for std::collections::binary_heap::Drain<'a, T> where
T: Sync,
impl<'a, T> Sync for std::collections::binary_heap::Iter<'a, T> where
T: Sync,
impl<'a, T> Sync for std::collections::btree_set::Iter<'a, T> where
T: Sync,
impl<'a, T> Sync for std::collections::btree_set::Range<'a, T> where
T: Sync,
impl<'a, T> Sync for std::collections::btree_set::Union<'a, T> where
T: Sync,
impl<'a, T> Sync for std::collections::vec_deque::Iter<'a, T> where
T: Sync,
impl<'a, T> Sync for std::result::Iter<'a, T> where
T: Sync,
impl<'a, T, F> !Sync for std::collections::linked_list::DrainFilter<'a, T, F>
impl<'a, T, S> Sync for std::collections::hash_set::Union<'a, T, S> where
S: Sync,
T: Sync,