Приклади

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: Sync>: Використовує примітиви рівня ОС, які мають бути звільнені у потоці, що їх створив. Проте, вже заблокований м'ютекс може мати захищену змінну, яку може читати будь-який потік, з яким розділяється захист.

!Send + !Sync

Ці типи є потоконебезпечними і не можуть бути переміщені в інші потоки:

  • Rc<T>: кожен Rc<T> має посилання на RcBox<T>, який містить неатомарний лічильник посилань.
  • *const T, *mut T: Rust припускає, що необроблені покажчики можуть мати особливі міркування щодо одночасного використання.