C++ 放松内存顺序自旋锁是否总是中断同步?

C++ 放松内存顺序自旋锁是否总是中断同步?,c++,atomic,memory-barriers,C++,Atomic,Memory Barriers,考虑以下代码: 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_relaxe

考虑以下代码:

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?
int非原子=0;
std::原子{0};
//线程1
非原子=1;
atom.store(1,std::memory\u order\u release);
//线程2
while(atom.load(std::memory_order_released)!=1);//自旋锁等待t1
atom.store(2,std::memory\u order\u released);
//线程3
如果(Atom。Load(STD::MexyYoOdRySub)=2)/考虑这是真的情况
int foo=nonatom;//读非原子的
//foo保证为1吗?
//未定义的行为?
如果线程3从
atom
读取值
2
,是否保证在
nonatom
中看到值
1

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

然而,通常非正式地说,发布保证在它之后不能对写入进行重新排序,而获取保证在它之前不能对读取进行重新排序,这使得在逻辑上似乎不可能在写入时或之前读取
nonatom


我对这一点的分析是,单从标准来看,代码是不正确的,但考虑到释放和获取通常是如何在机器代码中实现的,它实际上会在任何实际的实现中中断吗?您对这个例子的评价是什么?

Anthony Williams的《C++并发在行动》是一本好书,如果您对多线程很认真的话。谢谢您的推荐。但是,我不确定它是否能回答这个问题,因为这更多的是一个问题,即一个不严格兼容的代码是否仍然可以在已知实现的基础上在逻辑上保证工作。这本书有几个例子,但似乎没有一个与你的相符。我认为通过及物性,foo总是1。另一方面,如果我要编写代码,我可能会使用更安全的方法(线程2中的release/acquire)。LWimsey评论中的链接可能更有用。