Arc (Rust)
Arc<T> is an atomically reference-counted smart pointer for sharing ownership of a value across threads.
Why?
Sharing a Mutex across threads breaks Rust’s single-ownership rule. Reference counting fixes that, but the non-atomic
Rc<T>isn’t thread-safe, so we need an atomic variant.
Two reference-counted smart pointers ship in std:
Rc<T>: shared ownership within a single thread..clone()bumps the refcount, value drops at 0.!Send, so it can’t cross threadsArc<T>: atomic refcount. Slightly slower thanRc, butSend + Sync
Typical pattern: wrap a Mutex in an Arc to get shared, protected, mutable state:
let quit = Arc::new(Mutex::new(false));
let handler_quit = Arc::clone(&quit);
ctrlc::set_handler(move || {
let mut b = handler_quit.lock().unwrap();
*b = true;
});Caveats:
- Ref cycles between
Rc/Arcleak, the count never hits 0 - Unlike C++‘s
shared_ptr, you can’t keep a reference after theArcgoes out of scope; the value is owned by the pointer and freed when it drops Box<T>is the simpler sibling for putting data on the heap with single ownership
Deadlock still possible
Automatic unlock doesn’t prevent deadlock. Nothing stops thread 1 taking A then B while thread 2 takes B then A.