CodeBlanks Logo Icon CodeBlanks

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().

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

main.rs
use std::sync::Arc;
use std::thread;

fn main() {
    // buraya yaz
}

Sample solution

main.rs
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

Question
let v = Arc::____(&veri);
thread::spawn(move || v.len());
Answer
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

All lessons in Advanced