Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Примеры

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 считает, что у сырых указателей могут быть особые соображения относительно конкурентности.