Arc<T>
- Rust course
- Intermediate
- Lesson 32/115
- 4 min
Learn thread-safe shared ownership with Arc<T>.
Arc<T>
Arc<T> (atomically reference counted) is the thread-safe version of Rc. It updates the counter with atomic operations; it's slightly slower but can be shared across threads:
use std::sync::Arc;
use std::thread;
let veri = Arc::new(vec![1, 2, 3]);
let v = Arc::clone(&veri);
let h = thread::spawn(move || v.iter().sum::<i32>());
println!("{}", h.join().unwrap()); // 6Each thread takes its own Arc copy with move. The data is read-only; changing it needs Arc<Mutex<T>>.
Collecting results in order
The output order of threads is undetermined. Getting results with join both waits for them to finish and collects them in order:
let tutucular: Vec<_> = (1..=3)
.map(|k| {
let v = Arc::clone(&veri);
thread::spawn(move || v.iter().sum::<i32>() * k)
})
.collect();
let sonuc: Vec<i32> = tutucular.into_iter().map(|h| h.join().unwrap()).collect();Once all threads finish, their copies are dropped too and the counter is back to 1.
Practice Parallel sum
Share Arc::new(vec![1, 2, 3]). Start three threads for k = 1..=3, each computing sum * k, and collect the results in order with join. Print the result vector and the final Arc::strong_count value separated by a space.
Starter code
use std::sync::Arc;
use std::thread;
fn main() {
// buraya yaz
}Sample solution
use std::sync::Arc;
use std::thread;
fn main() {
let veri = Arc::new(vec![1, 2, 3]);
let tutucular: Vec<_> = (1..=3)
.map(|k| {
let v = Arc::clone(&veri);
thread::spawn(move || v.iter().sum::<i32>() * k)
})
.collect();
let sonuc: Vec<i32> = tutucular.into_iter().map(|h| h.join().unwrap()).collect();
println!("{:?} {}", sonuc, Arc::strong_count(&veri));
}Expected output
[6, 12, 18] 1
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 What happens if an <code>Rc</code> is used inside <code>thread::spawn(move || ..)</code>?
- It works but is slow
- Runtime panic
- No problem
- Compile error: Rc can't be sent safely between threads (not Send) Correct answer
Explanation: The compiler prevents data races at compile time with the Send/Sync traits.
2 Thread-safe sharing
use std::sync::Arc;
let veri = ____::new(vec![1, 2, 3]);
use std::sync::Arc;
let veri = Arc::new(vec![1, 2, 3]);
Explanation: Sharing across threads needs Arc, with its atomic counter.
3 Type and property
| Term | Meaning |
|---|---|
Rc<T> |
Single thread, sharing |
Arc<T> |
Multiple threads, sharing |
Box<T> |
Single owner |
Arc<Mutex<T>> |
Shared mutation |