I have something like this:
use std::sync::Arc;
fn main() {
let arc = Arc::new(42);
move || { arc.clone() };
move || { arc.clone() };
}
I am getting:
error[E0382]: capture of moved value: `arc`
--> src/main.rs:6:19
|
5 | move || { arc.clone() };
| ------- value moved (into closure) here
6 | move || { arc.clone() };
| ^^^ value captured here after move
|
= note: move occurs because `arc` has type `std::sync::Arc<i32>`, which does not implement the `Copy` trait
I understand why I am getting this: the clone isn't called before arc is passed to the closure. I can fix this by defining each closure in a function and clone the Arc before passing it to the closure, but is there another option?
Thread Safety Unlike Rc<T> , Arc<T> uses atomic operations for its reference counting. This means that it is thread-safe.
An integer the size of which is arch will be 32 bits on an x86 machine and 64 bits on an x64 machine.
There is no way around it. You should clone the Arc before it is used in a closure. The common pattern is to re-bind the cloned Arc to the same name in a nested scope:
use std::sync::Arc;
fn main() {
let arc = Arc::new(42);
{
let arc = arc.clone();
move || { /* do something with arc */ };
}
{
let arc = arc.clone();
move || { /* do something else with arc */ };
}
}
This is usually done together with thread::spawn():
use std::sync::{Arc, Mutex};
use std::thread;
const NUM_THREADS: usize = 4;
fn main() {
let arc = Arc::new(Mutex::new(42));
for _ in 0..NUM_THREADS {
let arc = arc.clone();
thread::spawn(move || {
let mut shared_data = arc.lock().unwrap();
*shared_data += 1;
});
}
}
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