19.7 Shared Ownership Across Threads with Arc<T>
Rc<T>
is single-threaded. If you need to share data across multiple threads, Rust provides Arc<T>
(Atomic Reference Counted). It functions like Rc<T>
but maintains the reference count using atomic operations, ensuring it’s safe to clone and use across threads.
19.7.1 Arc<T>
: Thread-Safe Reference Counting
- Increments and decrements the reference count using atomic instructions.
- Ensures data stays alive as long as there’s at least one
Arc<T>
in any thread. - Provides safe sharing across thread boundaries.
Example:
use std::sync::Arc; use std::thread; fn main() { let data = Arc::new(42); let handles: Vec<_> = (0..4).map(|_| { let data = Arc::clone(&data); thread::spawn(move || { println!("Data: {}", data); }) }).collect(); for handle in handles { handle.join().unwrap(); } }
19.7.2 Mutating Data Under Arc<T>
To allow mutation with shared ownership across threads, combine Arc<T>
with synchronization primitives like Mutex<T>
or RwLock<T>
:
use std::sync::{Arc, Mutex}; use std::thread; fn main() { let shared_num = Arc::new(Mutex::new(0)); let handles: Vec<_> = (0..4).map(|_| { let shared_num = Arc::clone(&shared_num); thread::spawn(move || { let mut val = shared_num.lock().unwrap(); *val += 1; }) }).collect(); for handle in handles { handle.join().unwrap(); } println!("Final value: {}", *shared_num.lock().unwrap()); }