Home > Software design >  chunks_exact_mut threading lifetimes
chunks_exact_mut threading lifetimes

Time:06-11

The following code produces interesting results:

use std::thread;

fn main() {
    let mut handles = Vec::new();
    let mut v = vec![1, 2, 3, 4];
    
    for x in v.chunks_exact_mut(2) {
        let handle = thread::spawn(move || {
            println!("Here's a vector: {:?}", x);
        });
        
        handles.push(handle);
    }

    for h in handles { h.join().unwrap(); }
}
error[E0597]: `v` does not live long enough
  --> src/main.rs:7:14
   |
7  |     for x in v.chunks_exact_mut(2) {
   |              ^^^^^^^^^^^^^^^^^^^^^
   |              |
   |              borrowed value does not live long enough
   |              argument requires that `v` is borrowed for `'static`
...
16 | }
   | - `v` dropped here while still borrowed

Why does 'chunking' v change the lifetime? Without 'chunking' v, the code performs correctly. So why now does it throw an error?

CodePudding user response:

The problem here is that thread::spawn completely decouples the lifetime from the rest, as the thread might continue to run while main is already finished.

x is a reference to a variable in main, and there is no guarantee that main lives longer than the thread.

I think what you really want here is a threading helper library like rayon, as they already solve those problems internally:

use rayon::prelude::*;

fn main() {
    let mut v = vec![1, 2, 3, 4];

    v.par_chunks_exact_mut(2).for_each(|x: &mut [i32]| {
        let thread_id = std::thread::current().id();
        println!("{:?}: Here's a vector: {:?}", thread_id, x);
    });
}
ThreadId(5): Here's a vector: [1, 2]
ThreadId(2): Here's a vector: [3, 4]
  • Related