Rust
Arc<T>
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().
Exercise 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.
Show example 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);
}
Test yourself
-
Apart from <code>Arc</code>, what is another way to do the same job without copies?
- Lending slices with thread::scope
- static mut
- Rc
- clone
Show answer
Lending slices with thread::scope — If the data is needed only during this computation, scope is simpler; if threads must outlive the function, Arc is needed.
-
Copy the pointer
let v = Arc::____(&veri);
thread::spawn(move || v.len());
Show answer
let v = Arc::clone(&veri);
thread::spawn(move || v.len());
-
Tool and use
- Arc<T>
- Read-only sharing
- Arc<Mutex<T>>
- Mutable sharing
- thread::scope
- Temporary borrow
- rayon
- Parallel iterator
Next lesson: Send and Sync