Примеры
Send + Sync
Большинство типов, с которыми вы сталкиваетесь, реализуют Send + Sync:
i8,f32,bool,char,&str, …(T1, T2),[T; N],&[T],struct { x: T }, …String,Option<T>,Vec<T>,Box<T>, …Arc<T>: явно потокобезопасен благодаря атомарному счётчику ссылок.Mutex<T>: явно потокобезопасен благодаря внутренней блокировке.mpsc::Sender<T>: начиная с 1.72.0.AtomicBool,AtomicU8, …: используют специальные атомарные инструкции.
Обобщённые типы обычно реализуют Send + Sync, когда их параметры типа реализуют Send + Sync.
Send + !Sync
Эти типы можно перемещать в другие потоки, но они не потокобезопасны. Обычно это из-за внутренней изменяемости:
mpsc::Receiver<T>Cell<T>RefCell<T>
!Send + Sync
К этим типам безопасно обращаться (через разделяемые ссылки) из нескольких потоков, но их нельзя переместить в другой поток:
MutexGuard<T>: использует примитивы уровня ОС, которые должны быть освобождены в потоке, который их создал. Однако уже заблокированный мьютекс может быть прочитан любым потоком, с которым разделён охранник (если только самTне!Sync).
!Send + !Sync
Эти типы не потокобезопасны и не могут быть перемещены в другие потоки:
Rc<T>: каждыйRc<T>содержит ссылку наRcBox<T>, в котором есть неатомарный счётчик ссылок.*const T,*mut T: Rust считает, что у сырых указателей могут быть особые соображения относительно конкурентности.