memory_order_acquire真的足以锁定自旋锁吗?

Sta*_*ked 7 c++ atomic

根据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_rellock()方法中需要一个标记,以确保在尝试锁定互斥锁的其他线程中锁定状态的可见性.

为什么memory_order_acquire足够?

Dav*_*eas 6

获取和释放不与此原子变量相关,而是与每个线程中读/写的其余变量相关.

为了使它更加明显,没有释放,unlock()并且lock()旗帜中的获取仍然是可见的.问题是释放锁之后可能会推送对由自旋锁保护的变量的写入,从而引入竞争条件.以同样的方式,锁内的该变量的读取可能会移动到之前lock()

  • @StackedCrooked读 - 修改 - 写操作很特殊.每29.3/12"原子读 - 修改 - 写操作应始终读取在与读 - 修改 - 写操作相关的写操作之前写入的最后一个值(按修改顺序)." 您为这样的RMW操作选择的内存顺序仅影响对其他内存位置的读/写操作以及对同一原子的非RMW操作的排序方式.就`atomic_flag`本身而言,`test_and_set`和`clear`都可以放宽并提供互斥 - 但它不会命令访问其他内存位置. (3认同)