Thread-Safe Arc(Atomically Reference Counted) = Shared pointer
data shared b/w threads (vec![1,2,3])
refCount 1 2 n
/\ /\ /\
| | |
Arc::clone() Arc::clone() Arc::clone()
thread-1 thread-2 thread-n
-
Arc provides shared ownership of immutable data across multiple threads,
With Arc::clone() reference count is incremented, and resource is freed when count=0
if you try to change data wrapped inside Arc, It gives compilation error
Features of Arc
- 1. Shared Ownership:
- When the last Arc pointer to a given allocation is destroyed, the value stored in that allocation (inner value) is also dropped.
- 2. Mutable References:
- If you need to mutate through an Arc, use Mutex, RwLock, or one of the Atomic types. Eg: Arc<Mutex<Value>> or Arc<RwLock<Value>>
- 3. Thread Safety:
- The disadvantage is that atomic operations are more expensive than ordinary memory accesses. Consider using Rc<T> for lower overhead
- 4. Send, Sync Triats on Arc <T>:
Changing data in Arc gives Compilation Error
use std::{sync::Arc, thread};
fn main() {
let mut data = Arc::new(vec![1,2,3]);
let mut handles = vec![];
for i in 0..3 {
let data_clone = Arc::clone(&data);
//data_clone[2] = 1; //Compilation Error
let h = thread::spawn(move||{
println!("{} {:?}",i, data_clone);
});
handles.push(h);
}
for i in handles {
i.join().unwrap();
}
}
Rc<T> vs Arc<T>
RC<T> (Reference Counted Smart Pointer) | Arc<T> (Atomically Reference Counted) | |
---|---|---|
What | Reference Counted Smart Pointer | Same (Internally Uses atomic operations for reference counting) |
Thread Safe | No | Yes |
What | Reference Counted Smart Pointer | Same |
Memory overhead | Less | More (Since it uses atomic operations Internally) |
clone() |
Invoking clone produces a new pointer to the same allocation in the heap When the last Rc pointer to a given allocation is destroyed, the value stored in that allocation (often referred to as “inner value”) is also dropped |
Same |