宽松的内存顺序自旋锁是否总是会破坏同步?

问题描述

考虑以下代码

int nonatom = 0;
std::atomic<int> atom{0};

// thread 1
nonatom = 1;
atom.store(1,std::memory_order_release);

// thread 2
while (atom.load(std::memory_order_relaxed)!=1); // spinlock waits for t1
atom.store(2,std::memory_order_relaxed);

// thread 3
if (atom.load(std::memory_oder_acquire)==2) // consider the case that this is true
    int foo = nonatom; // read non-atomic
// Is foo guaranteed to be 1?
// Undefined behavior?

如果线程 3 从 2 读取值 atom,是否保证在 1 中看到值 nonatom

从happens-before和synchronize-with关系的定义来看,不能说对nonatom的写入先于读取,因为t3的acquire与在线程 1 中释放,因为它不从释放序列读取,而是从另一个线程(线程 2)的存储中读取值。在这种情况下,线程 1 和线程 3 之间会出现数据竞争,因为操作会竞争相同的非原子,一个不会发生在另一个之前。

然而,通常非正式地说,释放保证写入不能在它之后重新排序,而获取保证读取不能在它之前重新排序,这使得 nonatom 在逻辑上看起来不可能同时被读取或在写入之前。

我对此的分析是,仅就标准而言,代码是不正确的,但考虑到通常在机器代码中实现释放和获取的方式,它实际上是否会破坏任何实际实现?您对这个例子有何评价?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)