πŸ”„

Threads & Channels β€” Ownership-Based Concurrency

"Don't communicate by sharing memory; share memory by communicating"

The scariest thing in concurrent programming is data races. Two threads writing the same memory simultaneously causes undefined behavior.

In Rust, this is a compile error. The rule that only one &mut T can exist applies across thread boundaries. Send/Sync traits verify at compile time whether types can safely move/share between threads.

Channels (mpsc)

let (tx, rx) = mpsc::channel();
thread::spawn(move || { tx.send(42).unwrap(); });

move closures transfer ownership to the thread. The sender can no longer use that value.

Mutex

let counter = Arc::new(Mutex::new(0));

Mutex ensures only one thread accesses data at a time. Wrapped in Arc for multi-thread sharing.

Key Points

1

Create OS threads with std::thread::spawn

2

Transfer data ownership to thread via move closure

3

Message passing via mpsc::channel() (ownership-transfer based)

4

Protect shared mutable state with Arc<Mutex<T>>

Pros

  • Data races are compile errors β€” concurrent bugs blocked at source
  • Thread safety guaranteed as types via Send/Sync traits

Cons

  • Compiler can't catch Mutex deadlocks
  • Arc<Mutex> boilerplate is heavier than other languages

Use Cases

Parallel data processing β€” auto-parallelize iterators with Rayon crate Web servers β€” per-request threads + shared state (DB pool, etc.)