std:π:Sync - Rust (original) (raw)
Trait std::marker::Sync1.0.0 [β] [src]
#[lang = "sync"]
pub unsafe auto trait Sync { }
Types for which it is safe to share references between threads.
This trait is automatically implemented when the compiler determines it's appropriate.
The precise definition is: a type T
is Sync
if &T
isSend. In other words, if there is no possibility ofundefined behavior (including data races) when passing&T
references between threads.
As one would expect, primitive types like u8 and f64are all Sync
, and so are simple aggregate types containing them, like tuples, structs and enums. More examples of basic Sync
types include "immutable" types like &T
, and those with simple inherited mutability, such as Box, Vec and most other collection types. (Generic parameters need to be Sync
for their container to be Sync
.)
A somewhat surprising consequence of the definition is that &mut T
is Sync
(if T
is Sync
) even though it seems like that might provide unsynchronized mutation. The trick is that a mutable reference behind a shared reference (that is, & &mut T
) becomes read-only, as if it were a & &T
. Hence there is no risk of a data race.
Types that are not Sync
are those that have "interior mutability" in a non-thread-safe form, such as cell::Celland cell::RefCell. These types allow for mutation of their contents even through an immutable, shared reference. For example the set
method on Cell takes &self
, so it requires only a shared reference &Cell. The method performs no synchronization, thus Cell cannot be Sync
.
Another example of a non-Sync
type is the reference-counting pointer rc::Rc. Given any reference &Rc, you can clone a new Rc, modifying the reference counts in a non-atomic way.
For cases when one does need thread-safe interior mutability, Rust provides atomic data types, as well as explicit locking viasync::Mutex and sync::RwLock. These types ensure that any mutation cannot cause data races, hence the types are Sync
. Likewise, sync::Arc provides a thread-safe analogue of Rc.
Any types with interior mutability must also use thecell::UnsafeCell wrapper around the value(s) which can be mutated through a shared reference. Failing to doing this isundefined behavior. For example, transmute-ing from &T
to &mut T
is invalid.
See the Nomicon for more details about Sync
.
impl Sync for [AtomicI32](../../std/sync/atomic/struct.AtomicI32.html "struct std::sync::atomic::AtomicI32")
impl Sync for [AtomicU16](../../std/sync/atomic/struct.AtomicU16.html "struct std::sync::atomic::AtomicU16")
impl<T> Sync for [AtomicPtr](../../std/sync/atomic/struct.AtomicPtr.html "struct std::sync::atomic::AtomicPtr")<T>
impl<T> !Sync for [RefCell](../../std/cell/struct.RefCell.html "struct std::cell::RefCell")<T> where T: ?[Sized](../../std/marker/trait.Sized.html "trait std:π:Sized"),
impl Sync for [AtomicUsize](../../std/sync/atomic/struct.AtomicUsize.html "struct std::sync::atomic::AtomicUsize")
impl<T> !Sync for [*mut T](../primitive.pointer.html) where T: ?[Sized](../../std/marker/trait.Sized.html "trait std:π:Sized"),
impl<T> !Sync for [*const T](../primitive.pointer.html) where T: ?[Sized](../../std/marker/trait.Sized.html "trait std:π:Sized"),
impl<T> !Sync for [Cell](../../std/cell/struct.Cell.html "struct std::cell::Cell")<T>
impl<'a, T> Sync for std::slice::[IterMut](../../std/slice/struct.IterMut.html "struct std::slice::IterMut")<'a, T> where T: [Sync](../../std/marker/trait.Sync.html "trait std:π:Sync"),
impl Sync for [AtomicU64](../../std/sync/atomic/struct.AtomicU64.html "struct std::sync::atomic::AtomicU64")
impl<'a, T> Sync for std::slice::[Iter](../../std/slice/struct.Iter.html "struct std::slice::Iter")<'a, T> where T: [Sync](../../std/marker/trait.Sync.html "trait std:π:Sync"),
impl Sync for [AtomicI8](../../std/sync/atomic/struct.AtomicI8.html "struct std::sync::atomic::AtomicI8")
impl Sync for [AtomicBool](../../std/sync/atomic/struct.AtomicBool.html "struct std::sync::atomic::AtomicBool")
impl Sync for [AtomicI16](../../std/sync/atomic/struct.AtomicI16.html "struct std::sync::atomic::AtomicI16")
impl Sync for [AtomicIsize](../../std/sync/atomic/struct.AtomicIsize.html "struct std::sync::atomic::AtomicIsize")
impl Sync for [AtomicI64](../../std/sync/atomic/struct.AtomicI64.html "struct std::sync::atomic::AtomicI64")
impl<T> !Sync for [NonNull](../../std/ptr/struct.NonNull.html "struct std::ptr::NonNull")<T> where T: ?[Sized](../../std/marker/trait.Sized.html "trait std:π:Sized"),
impl<T> !Sync for [UnsafeCell](../../std/cell/struct.UnsafeCell.html "struct std::cell::UnsafeCell")<T> where T: ?[Sized](../../std/marker/trait.Sized.html "trait std:π:Sized"),
impl Sync for [AtomicU32](../../std/sync/atomic/struct.AtomicU32.html "struct std::sync::atomic::AtomicU32")
impl Sync for [AtomicU8](../../std/sync/atomic/struct.AtomicU8.html "struct std::sync::atomic::AtomicU8")
impl<T> Sync for [Unique](../../std/ptr/struct.Unique.html "struct std::ptr::Unique")<T> where T: [Sync](../../std/marker/trait.Sync.html "trait std:π:Sync") + ?[Sized](../../std/marker/trait.Sized.html "trait std:π:Sized"),
impl<T> Sync for [LinkedList](../../std/collections/linked%5Flist/struct.LinkedList.html "struct std::collections::linked_list::LinkedList")<T> where T: [Sync](../../std/marker/trait.Sync.html "trait std:π:Sync"),
impl<'a, T> Sync for std::collections::linked_list::[Iter](../../std/collections/linked%5Flist/struct.Iter.html "struct std::collections::linked_list::Iter")<'a, T> where T: [Sync](../../std/marker/trait.Sync.html "trait std:π:Sync"),
impl<'a> Sync for std:π§΅:[Drain](../../std/string/struct.Drain.html "struct std:π§΅:Drain")<'a>
impl<T> Sync for std::sync::[Weak](../../std/sync/struct.Weak.html "struct std::sync::Weak")<T> where T: [Send](../../std/marker/trait.Send.html "trait std:π:Send") + [Sync](../../std/marker/trait.Sync.html "trait std:π:Sync") + ?[Sized](../../std/marker/trait.Sized.html "trait std:π:Sized"),
impl<'a, T> Sync for std::collections::linked_list::[IterMut](../../std/collections/linked%5Flist/struct.IterMut.html "struct std::collections::linked_list::IterMut")<'a, T> where T: [Sync](../../std/marker/trait.Sync.html "trait std:π:Sync"),
impl<'a, T> Sync for std::collections::vec_deque::[Drain](../../std/collections/vec%5Fdeque/struct.Drain.html "struct std::collections::vec_deque::Drain")<'a, T> where T: [Sync](../../std/marker/trait.Sync.html "trait std:π:Sync"),
impl<T> !Sync for [Rc](../../std/rc/struct.Rc.html "struct std::rc::Rc")<T> where T: ?[Sized](../../std/marker/trait.Sized.html "trait std:π:Sized"),
impl<T> Sync for [Arc](../../std/sync/struct.Arc.html "struct std::sync::Arc")<T> where T: [Send](../../std/marker/trait.Send.html "trait std:π:Send") + [Sync](../../std/marker/trait.Sync.html "trait std:π:Sync") + ?[Sized](../../std/marker/trait.Sized.html "trait std:π:Sized"),
impl<'a, T> Sync for std::vec::[Drain](../../std/vec/struct.Drain.html "struct std::vec::Drain")<'a, T> where T: [Sync](../../std/marker/trait.Sync.html "trait std:π:Sync"),
impl<T> !Sync for std::rc::[Weak](../../std/rc/struct.Weak.html "struct std::rc::Weak")<T> where T: ?[Sized](../../std/marker/trait.Sized.html "trait std:π:Sized"),
impl<T> Sync for [IntoIter](../../std/vec/struct.IntoIter.html "struct std::vec::IntoIter")<T> where T: [Sync](../../std/marker/trait.Sync.html "trait std:π:Sync"),
impl<T> !Sync for [Receiver](../../std/sync/mpsc/struct.Receiver.html "struct std::sync::mpsc::Receiver")<T>
impl<T> !Sync for [Sender](../../std/sync/mpsc/struct.Sender.html "struct std::sync::mpsc::Sender")<T>
impl<T: ?[Sized](../../std/marker/trait.Sized.html "trait std:π:Sized") + [Send](../../std/marker/trait.Send.html "trait std:π:Send")> Sync for [Mutex](../../std/sync/struct.Mutex.html "struct std::sync::Mutex")<T>
impl<'a, T: ?[Sized](../../std/marker/trait.Sized.html "trait std:π:Sized") + [Sync](../../std/marker/trait.Sync.html "trait std:π:Sync")> Sync for [MutexGuard](../../std/sync/struct.MutexGuard.html "struct std::sync::MutexGuard")<'a, T>
impl Sync for [Once](../../std/sync/struct.Once.html "struct std::sync::Once")
impl<T: ?[Sized](../../std/marker/trait.Sized.html "trait std:π:Sized") + [Send](../../std/marker/trait.Send.html "trait std:π:Send") + [Sync](../../std/marker/trait.Sync.html "trait std:π:Sync")> Sync for [RwLock](../../std/sync/struct.RwLock.html "struct std::sync::RwLock")<T>
impl<'a, T: ?[Sized](../../std/marker/trait.Sized.html "trait std:π:Sized") + [Sync](../../std/marker/trait.Sync.html "trait std:π:Sync")> Sync for [RwLockReadGuard](../../std/sync/struct.RwLockReadGuard.html "struct std::sync::RwLockReadGuard")<'a, T>
impl<'a, T: ?[Sized](../../std/marker/trait.Sized.html "trait std:π:Sized") + [Sync](../../std/marker/trait.Sync.html "trait std:π:Sync")> Sync for [RwLockWriteGuard](../../std/sync/struct.RwLockWriteGuard.html "struct std::sync::RwLockWriteGuard")<'a, T>