I have this code:
let mut is_ok_test = false;
let handle = thread::spawn(move || {
is_ok_test = true;
});
handle.join().unwrap();
if is_ok_test == true { println!("Success"); } else { println!("Test Failed") }
The is_ok_test variable always remains false. I don't understand why.
When modifying the variable inside I get a warning like this:
value assigned to `is_ok_test` is never read
maybe it is overwritten before being read?
unused variable: `is_ok_test`
did you mean to capture by reference instead?
I tried to add & but it doesn't work.
The answer from @cafce25 is correct, but another way is to use scoped thread, since you join the thread before checking is_ok_test:
let mut is_ok_test = false;
thread::scope(|s| {
s.spawn(|| {
is_ok_test = true;
});
});
if is_ok_test == true {
println!("Success");
} else {
println!("Test Failed")
}
Scoped threads can capture variables from the outer function (notice there is no move).
The problem is that due to move || {... and booleans being Copy instead of changing the outside boolean you create a copy of it inside the closure.
That's also what your warnings are referring to, the inner is_ok is never read.
You can share ownership between the new and the main thread by using an Arc. To get back mutability you can use an AtomicBool:
use std::sync::Arc;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering::Relaxed;
fn main() {
let mut is_ok_test = Arc::new(AtomicBool::new(false));
let handle = {
let is_ok_test = is_ok_test.clone();
std::thread::spawn(move || {
is_ok_test.store(true, Relaxed);
})
};
handle.join().unwrap();
if is_ok_test.load(Relaxed) == true { println!("Success"); } else { eprintln!("Test Failed") }
}
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