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>: 内部ロックにより明示的にスレッドセーフ。
  • AtomicBool, AtomicU8, …: 特別なアトミック命令を利用。

ジェネリクスは、型パラメタがSend + Syncであるとき、通常はSend + Syncです。

Send + !Sync

これらの型は別のスレッドにムーブすることができますが、このようなムーブはスレッドセーフではありません。通常は内部可変性がその原因です:

  • mpsc::Sender<T>
  • mpsc::Receiver<T>
  • Cell<T>
  • RefCell<T>

!Send + Sync

このような型はスレッドセーフですが、別のスレッドにムーブすることはできません:

  • MutexGuard<T: Sync>: Uses OS level primitives which must be deallocated on the thread which created them.

!Send + !Sync

このような型はスレッドセーフではないため、別のスレッドにムーブすることはできません:

  • Rc<T>: それぞれの Rc<T>RcBox<T>への参照を持っています。これは、アトミックでない参照カウントを持っています。
  • *const T, *mut T: Rust は、生ポインターは同時実行性に関する特別な考慮事項がある可能性があることを仮定しています。