根据Antony Williams的书" C++ Concurrency in Action",一个spinlock可以实现如下:
class spinlock_mutex {
std::atomic_flag flag;
public:
spinlock_mutex() : flag(ATOMIC_FLAG_INIT) {}
void lock() {
while (flag.test_and_set(std::memory_order_acquire)) ;
}
void unlock() {
flag.clear(std::memory_order_release);
}
};
Run Code Online (Sandbox Code Playgroud)
如果我理解正确,memory_order_acquire标记可确保使用该memory_order_release标记的最新商店操作的可见性.("释放操作与获取操作同步.")
由于test_and_set也是一个存储操作,我希望memory_order_acq_rel在lock()方法中需要一个标记,以确保在尝试锁定互斥锁的其他线程中锁定状态的可见性.
为什么memory_order_acquire足够?
获取和释放不与此原子变量相关,而是与每个线程中读/写的其余变量相关.
为了使它更加明显,没有释放,unlock()并且lock()旗帜中的获取仍然是可见的.问题是在释放锁之后可能会推送对由自旋锁保护的变量的写入,从而引入竞争条件.以同样的方式,锁内的该变量的读取可能会移动到之前lock()