本文介绍了std :: atomic< T> :: notify_all如何排序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

我希望下面的程序不会挂起.

I expect the below program not to hang.

如果在(1)中以相反的顺序观察到(2)和(3),则可能由于丢失通知而挂起:

If (2) and (3) are observed in reverse order in (1), it may hang due to lost notification:

#include <atomic>
#include <chrono>
#include <thread>


int main()
{
    std::atomic<bool> go{ false };

    std::thread thd([&go] {
        go.wait(false, std::memory_order_relaxed); // (1)
    });

    std::this_thread::sleep_for(std::chrono::milliseconds(400));

    go.store(true, std::memory_order_relaxed); // (2)
    go.notify_all();                           // (3)

    thd.join();

    return 0;
}

所以问题是这里会发生什么:

So the question is what would happen here:

  1. 该程序可能会挂起,我必须使用围栏来防止它挂起.究竟是什么栅栏,在哪里以及为什么?
  2. 程序可能无法挂起.那么如何防止重新排序呢?我不是在问实现,而是在问标准措辞.

推荐答案

标准规定:

  • 观察 X 的结果后,原子等待操作已阻塞,
  • X 按照 M 的修改顺序在 Y 之前,并且
  • Y 发生在原子通知操作调用之前.
  • the atomic waiting operation has blocked after observing the result of X,
  • X precedes Y in the modification order of M, and
  • Y happens before the call to the atomic notifying operation.

关于nofify_all:

在您的示例中,go( M )的初始化对应于 X ,而store(2)的初始化对应于 Y .初始化发生在调用等待之前,而存储发生在调用通知之前.存储发生在通知之前,因为它是有序的,在通知之前,并且这两个函数在同一个对象上操作.存储本身放松并不重要,因为存储顺序仅命令 surrounding 操作. [intro.races] 6.9.2.1.19 状态:

In your example the initialization of go(M) corresponds to X, and the store (2) to Y. The initialization happens-before the call to wait, and the store happens-before the call to notify. The store happens-before the notify because it is sequenced-before it, and both functions operate on the same object. It doesn't matter that the store itself is relaxed, since the memory order only orders surrounding operations. [intro.races] 6.9.2.1.19 states:

不幸的是,该标准在可见性方面含糊不清,但据我所知,可以保证观察通知未阻塞的等待调用可以观察到在该通知调用之前发生的最新更改(或稍后的值)-只是就像条件变量一样

Unfortunately the standard is rather vague regarding visibility, but as I understand it, a wait call that is unblocked by some notify call is guaranteed to observe the latest change that happened-before that notify call (or some later value) - just like it is the case for condition variables

不,您的程序无法挂起.

So no, your program cannot hang.

这篇关于std :: atomic&lt; T&gt; :: notify_all如何排序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-06 10:06