You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust内存重排问题验证:操作顺序与原子序影响

Rust内存重排疑问与验证
fn do_something_under_lock(
    is_locked: &AtomicBool,
    some_atomic_counter_1: &AtomicUsize,
    some_atomic_counter_2: &AtomicUsize,
) {
    read_and_write_non_atomic_memory_1_before_lock();
    read_and_write_non_atomic_memory_2_before_lock();
    some_atomic_counter_1.fetch_add(1, Ordering::Relaxed);
    some_atomic_counter_2.fetch_add(1, Ordering::Relaxed);

    let mut succeeded_acquire;
    loop {
        succeeded_acquire = is_locked
            .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed)
            .is_ok();

        if succeeded_acquire {
            read_and_write_non_atomic_memory_1_inside_lock();
            some_atomic_counter_1.fetch_add(2, Ordering::Relaxed);

            is_locked.store(false, Ordering::Release);
            break;
        }
    }

    read_and_write_non_atomic_memory_1_after_lock();
    read_and_write_non_atomic_memory_2_after_lock();
    some_atomic_counter_1.fetch_add(3, Ordering::Relaxed);
    some_atomic_counter_2.fetch_add(3, Ordering::Relaxed);
}

  1. 当函数被内联时,read_and_write_non_atomic_memory_1_before_lock(); 是否可以被重排到do_something_under_lock调用之前?

可以,直到遇到原子Acquire操作(因为Acquire会阻止操作被重排到自身之前)或针对同一内存的非原子操作(否则会破坏单线程逻辑)

  1. read_and_write_non_atomic_memory_1_before_lock(); 是否可以被重排到原子Acquire操作之后?

可以,因为原子Acquire不会阻止编译器将操作重排到自身之后

  1. read_and_write_non_atomic_memory_1_before_lock(); 是否可以被重排到read_and_write_non_atomic_memory_1_inside_lock();之后?

不可以,因为这些操作针对同一内存,必须保持代码中的执行顺序,否则会破坏单线程逻辑

  1. read_and_write_non_atomic_memory_1_inside_lock(); 是否可以被重排到原子Release操作之后?

不可以,因为原子Release会阻止这种重排

  1. read_and_write_non_atomic_memory_1_after_lock(); 是否可以被重排到Release操作之前?

可以,因为原子Release不会阻止操作被重排到自身之前

  1. read_and_write_non_atomic_memory_1_after_lock(); 是否可以被重排到read_and_write_non_atomic_memory_1_inside_lock();之前?

不可以,因为这些操作针对同一内存,必须保持代码中的执行顺序,否则会破坏单线程逻辑

  1. 当函数被内联时,read_and_write_non_atomic_memory_2_before_lock(); 是否可以被重排到do_something_under_lock调用之前?

可以,直到遇到原子Acquire操作(因为Acquire会阻止操作被重排到自身之前)或针对同一内存的非原子操作(否则会破坏单线程逻辑)

  1. read_and_write_non_atomic_memory_2_before_lock(); 是否可以被重排到read_and_write_non_atomic_memory_1_before_lock();之前?

可以,因为这些操作针对不同内存,且两者之间没有原子Acquire或Release操作

  1. read_and_write_non_atomic_memory_2_before_lock(); 是否可以被重排到原子Acquire操作之后?

可以,因为原子Acquire不会阻止编译器将操作重排到自身之后

  1. read_and_write_non_atomic_memory_2_before_lock(); 是否可以被重排到原子Release操作之后?

不可以,因为原子Release会阻止这种重排

  1. read_and_write_non_atomic_memory_2_after_lock(); 是否可以被重排到Release操作之前?

可以,因为原子Release不会阻止操作被重排到自身之前

  1. read_and_write_non_atomic_memory_2_after_lock(); 是否可以被重排到Acquire操作之前?

不可以,因为原子Acquire会阻止操作被重排到自身之前

  1. 当函数被内联时,some_atomic_counter_1.fetch_add(1, Ordering::Relaxed); 是否可以被重排到do_something_under_lock调用之前?

可以,直到遇到原子Acquire操作(因为Acquire会阻止操作被重排到自身之前)或针对同一原子内存的操作(否则会破坏单线程逻辑)

  1. some_atomic_counter_1.fetch_add(1, Ordering::Relaxed); 是否可以被重排到原子Acquire操作之后?

可以,因为原子Acquire不会阻止编译器将操作重排到自身之后

  1. some_atomic_counter_1.fetch_add(1, Ordering::Relaxed); 是否可以被重排到some_atomic_counter_1.fetch_add(2, Ordering::Relaxed);之后?

不可以,因为这些操作针对同一内存,必须保持代码中的执行顺序,否则会破坏单线程逻辑

  1. some_atomic_counter_1.fetch_add(2, Ordering::Relaxed); 是否可以被重排到原子Release操作之后?

不可以,因为原子Release会阻止这种重排

  1. some_atomic_counter_1.fetch_add(3, Ordering::Relaxed); 是否可以被重排到Release操作之前?

可以,因为原子Release不会阻止操作被重排到自身之前

  1. some_atomic_counter_1.fetch_add(3, Ordering::Relaxed); 是否可以被重排到some_atomic_counter_1.fetch_add(2, Ordering::Relaxed);之前?

不可以,因为这些操作针对同一内存,必须保持代码中的执行顺序,否则会破坏单线程逻辑

  1. 当函数被内联时,some_atomic_counter_2.fetch_add(1, Ordering::Relaxed); 是否可以被重排到do_something_under_lock调用之前?

可以,直到遇到原子Acquire操作(因为Acquire会阻止操作被重排到自身之前)或针对同一原子内存的操作(否则会破坏单线程逻辑)

  1. some_atomic_counter_2.fetch_add(1, Ordering::Relaxed); 是否可以被重排到some_atomic_counter_1.fetch_add(1, Ordering::Relaxed);之前?

可以,因为这些操作针对不同内存,且两者之间没有原子Acquire或Release操作

  1. some_atomic_counter_2.fetch_add(1, Ordering::Relaxed); 是否可以被重排到原子Acquire操作之后?

可以,因为原子Acquire不会阻止编译器将操作重排到自身之后

  1. some_atomic_counter_2.fetch_add(1, Ordering::Relaxed); 是否可以被重排到原子Release操作之后?

不可以,因为原子Release会阻止这种重排

  1. some_atomic_counter_2.fetch_add(3, Ordering::Relaxed); 是否可以被重排到Release操作之前?

可以,因为原子Release不会阻止操作被重排到自身之前

  1. some_atomic_counter_2.fetch_add(3, Ordering::Relaxed); 是否可以被重排到Acquire操作之前?

不可以,因为原子Acquire会阻止操作被重排到自身之前

  1. 若将以下代码中的Acquire改为Relaxed,会产生什么影响?
succeeded_acquire = is_locked
    .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed)
    .is_ok();

编译器不会指示CPU从全局内存加载最新的内存变更到本地核心缓存,可能使用陈旧内存,导致read_and_write_non_atomic_memory_1_inside_lock();出现竞态

  1. 若将以下代码中的Release改为Relaxed,会产生什么影响?
is_locked.store(false, Ordering::Release);

编译器不会指示CPU将本地核心缓存的内存变更同步到全局内存,其他核心可能使用陈旧内存,导致read_and_write_non_atomic_memory_1_inside_lock();出现竞态


内容的提问来源于stack exchange,提问作者Ivan Ivanyuk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 00:14:55