fnmain() { let a = thread::spawn(|| { // 原子操作修改 FLAG.store(true, Ordering::Relaxed); }); let b = thread::spawn(|| { // 原子操作读取 if FLAG.load(Ordering::Relaxed) { println!("Relaxed: Flag is set!"); } }); a.join().unwrap(); b.join().unwrap(); }
fnmain() { let a = thread::spawn(|| { let x = X.load(Ordering::Relaxed); Y.store(x, Ordering::Relaxed); }); let b = thread::spawn(|| { // 1 let y = Y.load(Ordering::Relaxed); // 2 X.store(42, Ordering::Relaxed); }); a.join().unwrap(); b.join().unwrap(); assert_eq!(X.load(Ordering::Relaxed), 42); // 有可能, b线程的1和2不互相依赖,可以指令重排成2和1 assert_eq!(Y.load(Ordering::Relaxed), 42); }
use std::{ sync::{ atomic::{AtomicBool, AtomicU64, Ordering}, Arc, }, thread, };
static S: AtomicU64 = AtomicU64::new(0); fnrelaxed() { let a = Arc::new(AtomicBool::new(false)); let b = Arc::new(AtomicBool::new(false)); let a_clone = a.clone(); let b_clone = b.clone();
let t1 = thread::spawn(move || { a.store(true, Ordering::Relaxed); if !b.load(Ordering::Relaxed) { S.fetch_add(1, Ordering::Relaxed); } });
let t2 = thread::spawn(move || { b_clone.store(true, Ordering::Relaxed); if !a_clone.load(Ordering::Relaxed) { S.fetch_add(1, Ordering::Relaxed); } });
t1.join().unwrap(); t2.join().unwrap(); }
fnmain() { let cnt = 100000; for _ in0..cnt { relaxed(); } // 结果可能大于10000 let s = S.load(Ordering::SeqCst); println!("s: {}", s); }
use std::{ sync::atomic::{AtomicPtr, Ordering}, thread, };
structData {} fngenerate_data() -> Data { Data {} } fnget_data() -> &'static Data { static PTR: AtomicPtr<Data> = AtomicPtr::new(std::ptr::null_mut());
letmut p = PTR.load(Ordering::Acquire);
if p.is_null() { p = Box::into_raw(Box::new(generate_data())); ifletErr(e) = PTR.compare_exchange( std::ptr::null_mut(), p, Ordering::Release, Ordering::Acquire, ) { // Safety: p comes from Box::into_raw right above, // and wasn't shared with any other thread. drop(unsafe { Box::from_raw(p) }); p = e; } }
// Safety: p is not null and points to a properly initialized value. unsafe { &*p } } fnmain() { let t1 = thread::spawn(|| get_data()); let t2 = thread::spawn(|| get_data()); let (ret1, ret2) = (t1.join().unwrap(), t2.join().unwrap()); assert_eq!(ret1 as *const _, ret2 as *const _); }