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

非原子对象访问的内存序:acquire-release可见性验证

关于C原子操作acquire-release语义与非原子对象可见性的问题
#include <stdatomic.h>
#include <stdlib.h>

void write(int *j, _Atomic int *i){
    *j = rand();
    atomic_store_explicit(i, 1, memory_order_release);
}

void read(int *j, _Atomic int *i){
    if(atomic_load_explicit(i, memory_order_acquire)){
        int var = *j;
        atomic_store_explicit(i, 0, memory_order_release);
    }
}

假设int *j和_Atomic int *i指向无关联的同一内存对象,两个线程分别无限循环执行上述write和read函数。请问:当atomic_load_explicit(i, memory_order_acquire)读取到atomic_store_explicit(i, 1, memory_order_release)写入的值时,int var = *j;是否必然读取到同一迭代中*j = rand();写入的值?

提问者的理解:

  1. 由于程序顺序,*j = rand(); 先序于(Sequenced before) atomic_store_explicit(i, 1, memory_order_release);。
  2. 若atomic_load_explicit(i, memory_order_acquire)读取到对应写入值,则前者与后者同步于(synchronizes with)。
  3. 同理,atomic_load_explicit(i, memory_order_acquire) 先序于(Sequenced before) int var = *j;。
  4. 因此,*j = rand(); 线程间先发生于(inter-thread happens before) int var = *j;。

根据C标准5.1.2.4/p20规则,*j = rand();是相对于int var = *j;的可见副作用(a visible side effect)。

核心问题:

通过带有synchronizes-with关系的acquire-release操作,是否真的能为**非原子对象(non-atomic object)**提供可见性保证?*j = rand();是否可能与atomic_store_explicit(i, 1, memory_order_release);重排序?或者atomic_load_explicit(i, memory_order_acquire)是否可能与int var = *j;重排序?

注:x86架构中读写操作不会与同类操作重排序,因此针对x86编译的汇编代码无法提供反例。


回答:

是的,int var = *j;必然会读取到同一迭代中*j = rand();写入的值,acquire-release语义完全可以为非原子对象提供跨线程的可见性保证,且不会发生你担心的重排序。

具体依据C标准的规则:

  • release语义约束:memory_order_release的原子存储操作会阻止编译器和硬件将它之前的任何内存操作(包括非原子的*j = rand();)重排序到它之后。也就是说,*j的写入一定会在i的release存储完成前完成,且所有对*j的修改都会被同步到内存中。
  • acquire语义约束:memory_order_acquire的原子加载操作会阻止编译器和硬件将它之后的任何内存操作(包括非原子的int var = *j;)重排序到它之前。也就是说,var对*j的读取一定会在i的acquire加载完成后执行。
  • 线程间先发生关系(inter-thread happens before):结合你梳理的先序关系和synchronizes-with关系,*j的写入明确线程间先发生于var的读取。根据C标准5.1.2.4/p20,如果一个副作用线程间先发生于一个读取操作,那么这个副作用就是该读取操作的可见副作用,读取必须得到这个副作用的结果。

即使在弱内存模型架构(如ARM、PowerPC)下,编译器和硬件也会严格遵守acquire-release的约束,不会出现你担心的重排序情况。x86因为本身是强内存模型,所以表现更严格,但这并不影响标准层面的保证。


内容的提问来源于stack exchange,提问作者Some Name

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 11:08:35