为什么这个spinlock需要memory_order_aquire_release而不是仅仅获取


// spinlockAcquireRelease.cpp
#include <atomic>
#include <thread>
class Spinlock{
std::atomic_flag flag;
public:
Spinlock(): flag(ATOMIC_FLAG_INIT) {}
void lock(){
while(flag.test_and_set(std::memory_order_acquire) ); // line 12
}
void unlock(){
flag.clear(std::memory_order_release);
}
};
Spinlock spin;
void workOnResource(){
spin.lock();
// shared resource
spin.unlock();
}

int main(){
std::thread t(workOnResource);
std::thread t2(workOnResource);
t.join();
t2.join();
}

在笔记中,它说:

如果有两个以上的线程使用spinlock,则lock方法的获取语义是不够的。现在,锁定方法是一种获取-释放操作。因此,第12行[对flag.test_and_set(std::memory_order_acquire)]的调用]中的内存模型必须更改为std::memory_order_acq_rel

为什么这个自旋锁可以用2个线程,但不能用2个以上的线程?导致这个spinlock出错的示例代码是什么?

来源:https://www.modernescpp.com/index.php/acquire-release-semantic

std::memory_order_acq_rel不是必需的。

互斥同步在2个线程之间。。一个线程释放数据,另一个线程获取数据。
因此,其他线程执行释放或获取操作是不相关的。

如果收购由一个独立的围栏处理,也许会更直观(更高效(:

void lock(){
while(flag.test_and_set(std::memory_order_relaxed) )
;
std::atomic_thread_fence(std::memory_order_acquire);
}
void unlock(){
flag.clear(std::memory_order_release);
}

多个线程可以在CCD_ 4上旋转,但是一个人设法读取更新的值并再次设置它(在单个操作中(。。只有该线程在while循环之后才获取受保护的数据。

最新更新