How to write a bool
once(or very rarely), atomically and to ensure a happened-before visibility for all other subsequent reads to it(which can happen from other threads/cores) ?!
Can this be done by an AtomicBool
with Ordering::SeqCst
for the write, and with all reads having Ordering::Relaxed
? (am I understanding this correctly?!)
In other words, does that kind of write ensure that something akin of a flush happened after it, visibility wise, so that any other reads after it see that value(instead of the previous value) after it's done ?
Furthermore, I assume that if an even more relaxed reading could happen, such as non-atomic reading, then it would be UB(undefined behavior) because, well it should be atomic read instead ?? Though it feels like in practice any normal read would still be akin to an atomic read, at least on x86_64? (unsure)
Is there perhaps any other way to ensure such a flush-write?
so that then any other subsequent reads could be free, maybe even be normal reads ? (unless, from above, normal reads of an atomicbool written value are UB?)
Here's a sample(playground link) with the aforementioned AtomicBool
for no reason(other than for whoever was wondering):
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use std::thread;
fn main() {
// Create a shared atomic boolean
let atomic_bool = Arc::new(AtomicBool::new(false));
// Clone the atomic boolean for each thread
let atomic_bool_clone = Arc::clone(&atomic_bool);
// Spawn a thread to write to the atomic boolean
let write_thread = thread::spawn(move || {
std::thread::sleep(std::time::Duration::from_millis(100));
// Write to the atomic boolean with SeqCst ordering
atomic_bool_clone.store(true, Ordering::SeqCst);
println!("Write thread finished writing.");
});
// Spawn a thread to read from the atomic boolean
let read_thread = thread::spawn(move || {
let value = atomic_bool.load(Ordering::Relaxed);
println!("Read thread waiting a bit, else it reads(too soon): {}", value);
std::thread::sleep(std::time::Duration::from_millis(300));
// Read from the atomic boolean with Relaxed ordering
let value = atomic_bool.load(Ordering::Relaxed);
println!("Read thread read value: {}", value);
});
// Wait for both threads to finish
write_thread.join().unwrap();
read_thread.join().unwrap();
}