根据Antony Williams的书 C ++ Concurrency in Action ,可以按如下方式实现自旋锁:
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);
}
};
如果我理解正确,memory_order_acquire
标记可确保使用memory_order_release
标记的最新商店操作的可见性。 (“释放操作与获取操作同步。”)
由于test_and_set
也是一个存储操作,我希望在memory_order_acq_rel
方法中需要一个lock()
标记,以确保其他线程中锁定状态的可见性。锁定互斥锁。
为什么memory_order_acquire
足够了?
答案 0 :(得分:6)
获取和释放不与此原子变量相关,而是与每个线程中读/写的其余变量相关。
为了使其更加明显,如果没有在unlock()
中发布,并且lock()
中的获取仍然可见。问题是,在释放锁定后,可以在推送对自旋锁保护的变量的写入,从而引入竞争条件。以同样的方式,锁内的变量读取可能会移到lock()