Hello, I am having a typical challenge with borrowing in Rust.
I want to use a for loop to spin up a couple threads. I want to wait on all threads in the outer function that creates them.
To accomplish this, I tried creating a Vec<JoinHandle<()>>
to hold the handles.
pub fn test_thread() {
let mut handle_list: Vec<JoinHandle<()>> = vec![];
for thread_id in 1..2u8 {
let thread_fn = move || {
for i in 1..500_000_000 {
println!("Hello {i} from thread {}", thread_id);
}
};
let handle = std::thread::spawn(thread_fn);
handle_list.push(handle);
}
handle_list[0].join(); // error appears here
}
Resulting error on .join()
call:
cannot move out of index of
Vec<JoinHandle<()>>
move occurs because value has typeJoinHandle<()>
, which does not implement theCopy
trait
What Else I've Tried
- Storing references to handles
Vec<&JoinHandle<()>>
- Using the
Box<T>
type to wrap references the join handles - Pre-allocating an array for
JoinHandle<()>
and wrapping inOption<T>
(see below)
Attempt: Wrap Option<JoinHandle<()>> in Array
pub fn test_thread() {
let mut handle_list: [Option<JoinHandle<()>>; 2] = [None, None];
for thread_id in 0..=1usize {
let thread_fn = move || {
for i in 1..500_000_000 {
println!("Hello {i} from thread {}", thread_id);
}
};
let handle = std::thread::spawn(thread_fn);
handle_list[thread_id] = Some(handle);
// handle_list.push(handle);
}
let handle_ptr = handle_list[0].as_ref().unwrap();
(&handle_ptr).join(); // 🚨 Error: cannot move out of a shared reference move occurs because value has type `JoinHandle<()>`, which does not implement the `Copy` trait
}
How do I go about solving this? Do I have to implement the
Copy
trait on Vec<JoinHandle<()>>
or something? What other options do I have? I want a reference to each JoinHandle<()>
, I am not trying to move them.