std::memory_order 对于 std::atomic<T>:: 等待

std::memory_order for std::atomic<T>::wait

根据cppreference,在C++20中std::atomic<T>中有waitnotify_onenotify_all。看起来他们让 std::atomic<T> 可以用作 futex

我在问为什么 wait 接受 std::memory_order 作为参数。因为我总是需要检查从等待中唤醒是否不是虚假的,所以我将在相应的负载中指定内存顺序:

  std::atomic<bool> x;

  while (x.load(std::memory_order_acquire) == false)
  {
     x.wait(false, std::memory_order_acquire);
  }

或者我应该指定 std::memory_order_relaxed 等待?是否存在 wait 后面没有 load 的情况?

对同一个对象的所有原子操作总是只有一个顺序,单线程内的顺序也包含在其中。也就是说,relaxed 无法对同一线程内同一对象的原子操作重新排序。

relaxed 内存顺序是相对于除特定原子操作之外的其他内存操作的顺序。所以 relaxed 可以很好地检查等待本身,但是当你想实际读取由释放线程写入的数据时 包含在原子值中,你将需要更强的内存顺序以确保它们的可见性。因此,如果有必要,您的外循环应该使用更合适的条件来获取可见性。

我针对此提案将此问题发布到 GitHub,并得到 a response std::atomic::wait 旨在在具有逻辑的 futex 上实现,特别是为了掩盖虚假唤醒.

所以,cppreference.com 是错误的:

These functions are allowed to unblock spuriously, i.e. return due to reasons other than value change or notification.

while 循环在我的示例中是多余的,我应该只使用:

std::atomic<bool> x;

x.wait(false, std::memory_order_acquire);