Home > database >  Modifying a bool variable inside a thread
Modifying a bool variable inside a thread

Time:11-16

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.

CodePudding user response:

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

CodePudding user response:

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") }
}
  • Related