Send & Sync

There are two special traits in Rust for concurrency semantics.

  • Send marks a structure safe to send between threads.

  • Sync marks a structure safe to share between threads.

  • (&T is Send)

These traits are what Rust uses to prevent data races.

They are automatically derived for all types if appropriate.

Automatically Derived

use std::thread;

#[derive(Debug)]
struct Thing;

// Can send between threads!
fn main() {
    let thing = Thing;
    
    thread::spawn(move || {
        println!("{:?}", thing);
    }).join().unwrap();
}

There are some notable types which are not Send or Sync.

Such as Rc, raw pointers, and UnsafeCell.

Example: Rc

use std::rc::Rc;
use std::thread;

// Does not work!
fn main() {
    let only_one_thread = Rc::new(true);

    thread::spawn(move || {
        println!("{:?}", only_one_thread);
    }).join().unwrap();
}

Example: Rc

error[E0277]: the trait bound `std::rc::Rc<bool>: std::marker::Send` is not satisfied
 --> <anon>:7:5
  |
7 |     thread::spawn(move || {
  |     ^^^^^^^^^^^^^ the trait `std::marker::Send` is not implemented for `std::rc::Rc<bool>`

Implementing

It’s possible to add the implementation of Send and Sync to a type.

struct Thing(*mut String);

unsafe impl Send for Thing {}
unsafe impl Sync for Thing {}

In these cases, the task of thread safety is left to the implementor.

Relationships

If a type implements both Sync and Copy then it can also implement Send.

Relationships

A type &T can implement Send if the type T also implements Sync.

unsafe impl<'a, T: Sync + ?Sized> Send for &'a T {}

Relationships

A type &mut T can implement Send if the type T also implements Send.

unsafe impl<'a, T: Send + ?Sized> Send for &'a mut T {}

Consequences

What are the consequences of having Send and Sync?

Consequences

Carrying this information at the type system level allows driving data race bugs down to a compile time level.

Preventing this error class from reaching production systems.

Send and Sync are independent of the choice of concurrency (async, threaded, etc.).