CodeBlanks Logo Icon CodeBlanks

Send and Sync

Learn the Send and Sync marker traits and why they matter.

Send and Sync

Rust's thread safety rests on two marker traits; they have no methods, and the compiler infers them automatically:

  • Send: ownership of the value can be moved to another thread.
  • Sync: the value can be accessed through &T from other threads (T: Sync ⇔ &T: Send).
// Send + Sync: i32, String, Vec<T>, Arc<T> (T: Send + Sync), Mutex<T> (T: Send)
// Send but not Sync: Cell<T>, RefCell<T>
// neither: Rc<T>, raw pointers

The signature of thread::spawn requires F: Send + 'static; that's why data races are prevented at compile time.

Compile-time checking

You can check at compile time whether a type is Send/Sync with empty-bodied generic functions:

fn send_mi<T: Send>() {}
fn sync_mi<T: Sync>() {}

send_mi::<Arc<Mutex<i32>>>();   // passes
sync_mi::<Arc<Mutex<i32>>>();   // passes
// send_mi::<Rc<i32>>();        // error: `Rc<i32>` cannot be sent between threads safely

Library authors use such tests to ensure their public types' thread safety isn't accidentally broken.

Practice Thread safety check

Write the send_mi and sync_mi functions above. Call both for Arc<Mutex<i32>> and send_mi for String; if it compiles, print denetim geçti.

Starter code

main.rs
use std::sync::{Arc, Mutex};

fn main() {
    // buraya yaz
}

Sample solution

main.rs
use std::sync::{Arc, Mutex};

fn send_mi<T: Send>() {}
fn sync_mi<T: Sync>() {}

fn main() {
    send_mi::<Arc<Mutex<i32>>>();
    sync_mi::<Arc<Mutex<i32>>>();
    send_mi::<String>();
    println!("denetim geçti");
}

Expected output

denetim geçti

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 Why isn't <code>Rc&lt;T&gt;</code> Send?

  • Because it uses the heap
  • Because it's Clone
  • It is Send
  • Its counter isn't atomic; if two threads change it at once, the count breaks Correct answer

Explanation: Arc does the same job with an atomic counter; it's slightly slower but is Send + Sync.

2 Movability bound

Question
fn send_mi<T: ____>() {}
Answer
fn send_mi<T: Send>() {}

Explanation: The Send bound checks that the type can be moved to another thread.

3 Type and property

Term Meaning
Arc<Mutex<i32>> Send + Sync
Rc<i32> Neither
RefCell<i32> Send, not Sync
*const i32 Raw pointer: neither

All lessons in Advanced