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

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.