我试图熟悉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 );
}
};
}
}
Run Code Online (Sandbox Code Playgroud)
例如,在http://en.cppreference.com/w/cpp/atomic/atomic_flag
和"并行行动"一书中提到了相同的内容.我也在SO的某处找到了它.
但我只是不明白它为什么会起作用!
想象一下,线程1调用lock(),test_and_set()返回0作为旧值 - >线程1获得锁定.
但随后线程2出现并尝试相同.现在因为没有发生"存储同步"(release,seq_cst_acq_rel),所以线程1的spin_lock存储应该是轻松的类型.
但是由此得出它不能与线程2的spin_lock读取同步.这应该使线程2能够从spin_lock读取值0,从而获得锁定.
我的错误在哪里?
你的错误是忘记了spin_lock是一个atomic_flag,因而test_and_set是一个原子操作.的memory_order_acquire和memory_order_release从所述锁定操作之前迁移到需要的,以防止读出或从解锁后迁移到写入.锁本身受原子性保护,原子性始终包括可见性.
| 归档时间: |
|
| 查看次数: |
3425 次 |
| 最近记录: |