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
Create OS threads with std::thread::spawn
Transfer data ownership to thread via move closure
Message passing via mpsc::channel() (ownership-transfer based)
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