4

I am new to Rust and I am struggling with the concept of borrowing.

I want to load a Vec<Vec<f64>> matrix and then process it in parallel. However when I try to compile this piece of code I get error: capture of moved value: `matrix` [E0382] at the let _ = line.

This matrix is supposed to be readonly for the threads, they won't modify it. How can I pass it readonly and make the "moved value" error go away?

fn process(matrix: &Vec<Vec<f64>>) {
    // do nothing for now
}

fn test() {
    let filename = "matrix.tsv";
    // loads matrix into a Vec<Vec<f64>>
    let mut matrix = load_matrix(filename);

    // Determine number of cpus
    let ncpus = num_cpus::get();
    println!("Number of cpus on this machine: {}", ncpus);
    for i in 0..ncpus {
        // In the next line the "error: capture of moved value: matrix" happens
        let _ = thread::spawn(move || {
            println!("Thread number: {}", i);
            process(&matrix);
        });
    }
    let d = Duration::from_millis(1000 * 1000);
    thread::sleep(d);
}
1
  • 1
    There are many questions about dividing processing of slices / vectors to multiple threads. I found this one, this one, and this one with a small amount of searching. Commented Mar 20, 2016 at 23:54

1 Answer 1

4

Wrap the object to be shared into an Arc which stands for atomically reference counted (pointer). For each thread, clone this pointer and pass ownership of the clone to the thread. The wrapped object will be deallocated when it's no longer used by anything.

fn process(matrix: &Vec<Vec<f64>>) {
    // do nothing for now
}

fn test() {
    use std::sync::Arc;
    let filename = "matrix.tsv";
    // loads matrix into a Vec<Vec<f64>>
    let mut matrix = Arc::new(load_matrix(filename));

    // Determine number of cpus
    let ncpus = num_cpus::get();
    println!("Number of cpus on this machine: {}", ncpus);
    for i in 0..ncpus {
        let matrix = matrix.clone();
        let _ = thread::spawn(move || {
            println!("Thread number: {}", i);
            process(&matrix);
        });
    }
    let d = Duration::from_millis(1000 * 1000);
    thread::sleep(d);
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks that works great!. I have no idea, what you are doing, but hey i am going to look it up and learn ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.