Here is the Rust code snippet:
use std::thread;
use std::sync::atomic::{AtomicBool, AtomicI32};
use std::sync::atomic::Ordering::Relaxed;
static DATA: AtomicI32 = AtomicI32::new(0);
static READY: AtomicBool = AtomicBool::new(false);
fn main()
{
//child thread
let t = thread::spawn(||
{
DATA.store(123, Relaxed);
READY.store(true, Relaxed);
});
// parent thread
t.join().expect("Thread is panicked!");
while !READY.load(Relaxed)
{
println!("waiting..");
}
println!("{}", DATA.load(Relaxed));
}
The code snippet uses only Relaxed ordering which does not enforce the happens-before relationship among or between threads. However, the join()
method guarantees a happens-before relationship between what happened in the spawned/child thread and what happens after the join()
call. Here the child thread is the modifying-thread and the parent thread is only accessing the data, so the parent thread observing the changes made by the child thread is paramount.
Do you think the join()
method gives the guarantee to the main thread that it observes all the changes that happened in the child/spawned thread after the join()
method call?
I am asking here because I am confused that Relaxed ordering might not force the changes that happened to DATA
and READY
in the child thread to be observed immediately and in no delayed manner(before the parent thread finishes its execution) to be observed in the main/parent thread.