I'm reading the book "Rust Atomic and Locks" and encounters the following code:
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering::Relaxed;
fn main() {
static STOP: AtomicBool = AtomicBool::new(false);
// Spawn a thread to do the work.
let background_thread = thread::spawn(|| {
while !STOP.load(Relaxed) {
some_work();
}
});
// Use the main thread to listen for user input.
for line in std::io::stdin().lines() {
match line.unwrap().as_str() {
"help" => println!("commands: help, stop"),
"stop" => break,
cmd => println!("unknown command: {cmd:?}"),
}
}
// Inform the background thread it needs to stop.
STOP.store(true, Relaxed);
// Wait until the background thread finishes.
background_thread.join().unwrap();
}
The happens-befores relation rule says that in a single thread, everything just happens as the code order. Therefore I assume user input "stop" before storing true to STOP;
However, since the STOP atomic uses relaxed ordering, I assume that there's no happen-before relation between storing true to STOP and the point where the background thread reads true. Therefore I think there's no way I can ensure that the user input "stop" before the background thread received true in STOP, which means the background thread may break before the user input "stop".
I think I must be wrong but I dont know why. Any help?