Arc<T>
- Rust course
- Advanced
- Lesson 16/81
- 4 min
Share data across threads with Arc<T>.
Arc<T>
Arc<T> lets read-only data be shared across threads; if changes are needed, a Mutex/RwLock is put inside. A typical use is splitting large data into chunks without copying and giving each chunk to a separate thread:
let veri: Arc<Vec<u32>> = Arc::new((1..=9).collect());
let tutucular: Vec<_> = (0..3)
.map(|i| {
let v = Arc::clone(&veri);
thread::spawn(move || v[i * 3..i * 3 + 3].iter().sum::<u32>())
})
.collect();Each thread takes only an 8-byte pointer copy; the vector itself sits in memory just once.
Splitting into chunks
chunks(n) splits a slice into pieces of n. Choosing the number of chunks by the core count is a good start: std::thread::available_parallelism().
let parca_boyu = veri.len().div_ceil(4);
for parca in veri.chunks(parca_boyu) {
// each chunk to a thread
}In real projects the rayon crate does this in one line: veri.par_iter().sum().
Practice Parallel chunk sums
Share the numbers 1 to 9 in an Arc<Vec<u32>>. Let three threads each sum a chunk of three elements. Print the chunk sums and the overall sum 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<Vec<u32>> = Arc::new((1..=9).collect());
let tutucular: Vec<_> = (0..3)
.map(|i| {
let v = Arc::clone(&veri);
thread::spawn(move || v[i * 3..i * 3 + 3].iter().sum::<u32>())
})
.collect();
let parcalar: Vec<u32> = tutucular.into_iter().map(|h| h.join().unwrap()).collect();
let toplam: u32 = parcalar.iter().sum();
println!("{:?} {}", parcalar, toplam);
}Expected output
[6, 15, 24] 45
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 Apart from <code>Arc</code>, what is another way to do the same job without copies?
- Lending slices with thread::scope Correct answer
- static mut
- Rc
- clone
Explanation: If the data is needed only during this computation, scope is simpler; if threads must outlive the function, Arc is needed.
2 Copy the pointer
let v = Arc::____(&veri);
thread::spawn(move || v.len());
let v = Arc::clone(&veri);
thread::spawn(move || v.len());
Explanation: Arc::clone only increments the counter; it doesn't copy the data.
3 Tool and use
| Term | Meaning |
|---|---|
Arc<T> |
Read-only sharing |
Arc<Mutex<T>> |
Mutable sharing |
thread::scope |
Temporary borrow |
rayon |
Parallel iterator |