Help please with confusing thread errors

I don't understand how to fix these errors and am having trouble finding solutions on google.

borrowed value does not live long enough
   |                  argument requires that `entries` is borrowed for `'static`
cannot move out of index of `std::vec::Vec<std::thread::JoinHandle<i32>>`

(Playground)

chunks returns an iterator that produces slices, so chunk.clone() is a slice. Therefore, this loop:

for chunk in entries.chunks(entries.len() / 5) {
    t_paths.push(chunk.clone());
}

inserts slices that reference entries into t_paths; it should be

for chunk in entries.chunks(entries.len() / 5) {
    t_paths.push(chunk.to_vec());
}

instead, if you intend to clone the paths. (Alternatively, you could use scoped threads to be able to reference entries from the threads.)


for path in t_path {
    // ...
}
drop(t_path);

t_path is consumed by the loop, so the drop(t_path) should be removed.


// for h in thread_handles {
//     h.join().unwrap();
// }
let meh: i32 = thread_handles[0].join().unwrap();

The loop would work, but this doesn't. thread_handles[0] returns a (possibly mutable) reference to the thread; you need to take ownership if you intend to join:

let mut threads = thread_handles.into_iter();

// takes ownership of the first thread
let meh = threads.next().unwrap().join().unwrap();

// the rest of the threads should probably still be joined
for thread in threads {
    thread.join().unwrap();
}

These will fix the compilation errors.

Some other things to consider:

  • Instead of calling unwrap everywhere, it is probably easier to make main return Box<dyn Error> and using the ? operator.

  • This loop:

    let mut t_paths = Vec::new();
    
    for chunk in entries.chunks(entries.len() / 5) {
        t_paths.push(chunk.to_vec());
    }
    

    can be simplified to

    let t_paths: Vec<_> = entries
        .chunks(entries.len() / 5)
        .map(|s| s.to_vec())
        .collect();
    
  • Using derive(Default) is preferable to unsafe { mem::zeroed() }.

chunk.clone() didn't give you a Vec, but merely a copy of a temporary slice. Temporary slices are tied to the function scope they come from, and can't be sent to a new thread (when compiler says it wants 'static' it's actually saying that references are forbidden there).

You need chunk.to_vec() instead.

Don't write drop(t_path). You don't need to drop things manually. for path in t_path has already destroyed the value.

thread.join() makes the handle "self-destruct" (takes ownership of it), so this handle cannot be allowed to exist after this call.

This is in conflict with thread_handles[0].join() where thread_handles[0] continues to exist after the join() call (Vec can't have "holes")

thread_handles.remove(0).join() solves the problem by removing the handle from the vec, so that it can be taken by join().