Consider the following code example, I have a vector of JoinHandlers
in which I need it iterate over to join back to the main thread, however, upon doing so I am getting the error error: cannot move out of borrowed content
.
let threads = Arc::new(Mutex::new(Vec::new()));
for _x in 0..100 {
let handle = thread::spawn(move || {
//do some work
}
threads.lock().unwrap().push((handle));
}
for t in threads.lock().unwrap().iter() {
t.join();
}
Unfortunately, you can't do this directly. When Mutex
consumes the data structure you fed to it, you can't get it back by value again. You can only get &mut
reference to it, which won't allow moving out of it. So even into_iter()
won't work - it needs self
argument which it can't get from MutexGuard
.
There is a workaround, however. You can use Arc<Mutex<Option<Vec<_>>>>
instead of Arc<Mutex<Vec<_>>>
and then just take()
the value out of the mutex:
for t in threads.lock().unwrap().take().unwrap().into_iter() {
}
Then into_iter()
will work just fine as the value is moved into the calling thread.
Of course, you will need to construct the vector and push to it appropriately:
let threads = Arc::new(Mutex::new(Some(Vec::new())));
...
threads.lock().unwrap().as_mut().unwrap().push(handle);
However, the best way is to just drop the Arc<Mutex<..>>
layer altogether (of course, if this value is not used from other threads).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With