3

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);
}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Mandragor
  • 4,684
  • 7
  • 25
  • 40
  • 1
    There are **many** questions about dividing processing of slices / vectors to multiple threads. I found [this one](http://stackoverflow.com/q/28599334/155423), [this one](http://stackoverflow.com/q/33818141/155423), and [this one](http://stackoverflow.com/q/31644152/155423) with a small amount of searching. – Shepmaster Mar 20 '16 at 23:54

1 Answers1

3

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);
}
A.B.
  • 15,364
  • 3
  • 61
  • 64
  • Thanks that works great!. I have no idea, what you are doing, but hey i am going to look it up and learn ;) – Mandragor Mar 20 '16 at 22:01