在记忆顺序上,relaxed和acquire有什么区别?

问题描述 投票:0回答:0
use std::sync::atomic::AtomicPtr;
fn get_data() -> &'static Data {
    static PTR: AtomicPtr<Data> = AtomicPtr::new(std::ptr::null_mut());

    let mut p = PTR.load(Acquire);

    if p.is_null() {
        p = Box::into_raw(Box::new(generate_data()));
        if let Err(e) = PTR.compare_exchange(
            std::ptr::null_mut(), p, Release, 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 }
}

如果我把第一个PTR.load改成Relaxed,会有什么效果?

来自Rust Atomics and Locks,但是没有对第一个PTR.load做解释。我不太明白为什么我不能在这里使用Relaxed。

我认为发布交换保证了对象将被完全创建,所以加载操作不会得到旧的或不完整的数据。而在PTR.load(Acquire)时也会出现多个线程可能同时检测到PTR中的空指针,可能会有多个线程尝试创建并初始化Data对象。所以我不知道这里的效果。

rust atomic memory-barriers
© www.soinside.com 2019 - 2024. All rights reserved.