我正在尝试熟悉 c++11 的新内存排序概念,并相信我实际上对它们有很好的掌握,直到我偶然发现了自旋锁的这种实现:
#include <atomic>
namespace JayZ
{
namespace Tools
{
class SpinLock
{
private:
std::atomic_flag spin_lock;
public:
inline SpinLock( void ) : atomic_flag( ATOMIC_FLAG_INIT ) {}
inline void lock( void )
{
while( spin_lock.test_and_set( std::memory_order_acquire ) )
;
}
inline void unlock( void )
{
lock.clear( std::memory_order_release );
}
};
}
}
例如,在http://en.cppreference.com/w/cpp/atomic/atomic_flag
和“Concurrency in Action”一书中等价地提到了它。我还在 SO 的某个地方找到了它。
但我就是不明白为什么它会起作用!
想象一下线程 1 调用 lock() 并且 test_and_set() 返回 0 作为旧值 --> 线程 1 获得了锁。
但随后线程 2 出现并尝试相同。现在由于没有发生“存储同步”(release,seq_cst_acq_rel) 线程 1 到 spin_lock 的存储应该是放松类型。
但由此得出,它不能与线程 2 对 spin_lock 的读取同步。这应该使线程 2 可以从 spin_lock 读取值 0 并因此也获取锁。
我的错误在哪里?