compare_exchange_strong/weak 是否可以看到较旧的值?

问题描述

我实现了一个并发算法,其中我使用了大量的比较和交换。现在,我想通过处理内存排序来优化吞吐量,这让我想到了一些特定的问题。它基本上归结为以下代码结构:

atomic_int x = 0;

void thread1() {
  int a = atomic_load_explicit(&x,memory_order_relaxed);
  compare_exchange_strong_explicit(&x,&a,1,memory_order_relaxed,memory_order_relaxed);
  a = atomic_load_explicit(&x,memory_order_relaxed);
}

void thread2() {
  int a = 0;
  compare_exchange_strong_explicit(&x,2,memory_order_relaxed);
}

现在假设线程 2 的 compare_exchange 成功,线程 1 加载旧值 0 的情况仍然可能发生。但是,第一个线程的 compare-exchange 是否也会成功,因为底层操作仍然看到旧(预期)值?

如果不是,那么在这种情况下,比较交换肯定会失败。但是第二次加载呢? 由于宽松的内存排序,它还能读取旧值吗? compare_exchange 是否“强制”刷新此特定线程的内存子系统?

提前致谢!

解决方法

对特定原子对象的所有原子操作都保证对每个线程以相同的所谓对象修改顺序可见,即它们始终一致地出现。 (否则,无论如何,原子的整个想法对我来说都没有多大意义。)

另一方面,当单个线程准确感知更改时,完全取决于“实现”,即编译器和/或运行时。因为架构与您所期望的有很大不同,这里,这是 C 标准所说的“实现质量”问题,也就是说,如果您认为它们是,您必须向编译器编写者或芯片构造函数抱怨太慢了,例如

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...