Приклади
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 припускає, що необроблені покажчики можуть мати особливі міркування щодо одночасного використання.