我试图理解内存模型并读取5.1.2.4 Multi-threaded executions and data races,并对5.1.2.4(p10)中定义的发布序列概念感到困惑,如下所示:
由原子对象
A上的释放操作M领导的释放序列是M修改顺序中副作用的最大连续子序列,其中第一个操作是A,随后的每个操作要么由执行释放的同一个线程执行,要么是原子读-修改-写入操作。
它随后用于定义与at 5.1.2.4(p11)的同步,如下所示:
某些库调用与另一个线程执行的其他库调用同步。特别地,对对象
A执行释放操作的原子操作B与对M执行获取操作的原子操作B同步,并读取由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);
}我目前将其理解为A是atomic_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); )可见。
是对的还是我漏掉了什么?
发布于 2019-04-12 12:19:25
不,序列包括所有四个存储操作,因为中间加载操作由同一个线程完成。基本上,对于您的示例来说,您不必引用同步。因为游戏中只有一个线程,“先排序”已经给出了你想要的所有信息。优化器甚至可以省略除简化示例中的最后一个之外的所有存储,甚至对于原子操作也是如此。( volatile在atomic_store规范中是有的,但我们暂时不要提这个问题了。)
我认为,发布序列的概念是确定不同线程的读取可以截取存储值的点,并且在序列中的第一个存储操作之后使读取变得可靠。因此,线程读取它所写入的值的事实可以忽略。
https://stackoverflow.com/questions/55646969
复制相似问题