了解发布顺序并与C11同步

问题描述 投票:1回答:1

我正在尝试理解记忆模型并读取5.1.2.4 Multi-threaded executions and data races,并且被5.1.2.4(p10)定义的释放序列概念混淆如下:

由原子对象A上的释放操作M引导的释放序列是M的修改顺序中的最大连续副作用子序列,其中第一个操作是A,并且每个后续操作或者由执行的相同线程执行发布或是原子读 - 修改 - 写操作。

随后用于定义与5.1.2.4(p11)同步如下:

某些库调用与另一个线程执行的其他库调用同步。特别地,对对象A执行释放操作的原子操作M与对B执行获取操作的原子操作M同步,并且读取由A为首的释放序列中的任何副作用所写的值。

我可以想象下面的例子:

#include <stdatomic.h>
Atomic_ int a; // <<--- M

int main(void){
    atomic_store_explicit(&a, 42, memory_order_release); // <<--- A
    atomic_store_explicit(&a, 442, memory_order_release); 
    atomic_store_explicit(&a, 242, memory_order_release); 
    int a_value = atomic_load_explicit(&a, memory_order_acquire);
    atomic_store_explicit(&a, 242, memory_order_release);
}

我目前理解为Aatomic_store_explicit(&a, 42, memory_order_release);,它的释放序列是

atomic_store_explicit(&a, 442, memory_order_release); 
atomic_store_explicit(&a, 242, memory_order_release); 

atomic_store_explicit(&a, 242, memory_order_release);不包括在内,因为接下来是int a_value = atomic_load_explicit(&a, memory_order_acquire);,这是一项收购行动。

现在来到synchronize with,对对象M执行释放操作的原子操作A与对M执行获取操作的原子操作B同步并读取由A标题的释放序列中的任何副作用写入的值意味着A的释放序列中的所有释放操作都是通过atomic_load_explicit(&a, memory_order_acquire);的获取操作可见的

这是正确的还是我错过了什么?

c multithreading concurrency c11 memory-model
1个回答
3
投票

不,序列包括所有四个存储操作,因为中间加载操作由同一个线程完成。基本上对于您的示例,您不必参考同步。由于游戏中只有一个线程,“之前排序”已经为您提供了所需的所有信息。优化器甚至可以省略所有存储,但是在简化示例中是最后一个存储,即使对于原子操作也是如此。 (那么volatile的规格中有atomic_store,但暂时不要忘记这一点。)

我认为,释放序列概念的概念是识别不同线程的读取可以拦截存储值的点,并且在序列中的第一个存储操作之后使读取依赖性排序。为此,可以忽略线程读取其写入的值的事实。

© www.soinside.com 2019 - 2024. All rights reserved.