在存储之后用原子上的发行内存顺序调用notify_all方法

发布于 2025-02-08 11:54:55 字数 565 浏览 3 评论 0原文

我在单个线程上执行以下代码(用C ++ 20):

std::atomic_bool is_ready{};

void SetReady() {
  is_ready.store(true, std::memory_order_release);
  is_ready.notify_all();
}

其他线程执行以下列出的文本:

void Wait() {
  is_ready.wait(false, std::memory_order_acquire);
}

众所周知,发行记忆顺序不能确保未确定其后的操作不会由它重新排序编译器。那么,我可以在store()之后放置notify_all(),然后使用发行内存订单?安全吗?只是我有一些想法,即store()可以在notify_all()之前进行测序,因此不得重新排序。

I have the following code being executed on a single thread (written in C++20):

std::atomic_bool is_ready{};

void SetReady() {
  is_ready.store(true, std::memory_order_release);
  is_ready.notify_all();
}

Other threads execute the text listed below:

void Wait() {
  is_ready.wait(false, std::memory_order_acquire);
}

As I know, release memory order doesn't ensure that the operations located after it will not be reordered by a compiler. So, can I place notify_all() after store() with release memory order? Is it safe? Just I have some thoughts that store() may be sequenced before notify_all() and hence may not be reordered.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

長街聽風 2025-02-15 11:54:56

记忆订单在这里是无关紧要的。它们只会影响内存访问的排序其他而不是在原子本身上,而您没有。

编译器无法在商店之前重新排序notify_all在商店之前致电,因为 notify_all被指定 唤醒原子上的所有等待操作,该操作是 有资格被封锁

这些取决于在全球修改顺序原子,最后一家 notify_all的呼叫是在等待线程被阻止时观察到的商店后订购的。

在您所显示的代码中true存储是 序列 notify_all呼叫(在同一线程中),这意味着商店发生在呼叫之前,但是如果行切换了行,那就不再是这种情况了。

因此,将notify_all移动到商店因此可能会更改有资格无障碍的等待操作集。

如果允许编译器这样做,那么等待/通知机制将是没有用的。这也与同一线程中同一原子上的其他操作(或在同一线程中同一存储位置上的任何操作)中的其他操作相同。编译器也不能重新排序这些。

因此,是的,它是安全的,等待线程不会永远等待。 (我假设初始化std :: atomic_bool is_ready {};正在发生在所显示的任何一个线程函数开始执行之前。)

The memory orders are irrelevant here. They only affect ordering of memory access other than on the atomic itself and you have none.

The compiler cannot reorder the notify_all call before the store in any case, because notify_all is specified to wake up all waiting operations on the atomic which are eligible to be unblocked.

Which these are depends on whether, in the global modification order of the atomic, the last store which happens-before the call to notify_all is ordered after the store observed by the waiting thread when it blocked.

In your shown code the true store is sequenced-before the notify_all call (in the same thread), which implies that the store happens-before the call, but if the lines were switched, then that wouldn't be the case anymore.

Moving the notify_all before the store would thus potentially change the set of waiting operations which are eligible to be unblocked.

If the compiler was allowed to do that, then the waiting/notification mechanism would be pretty useless. This is also the same as for other operations on the same atomic in the same thread (or really any operations on the same storage location in the same thread). The compiler cannot reorder these either.

So yes, it is safe and the Wait thread will not wait forever. (I am assuming that the initialization std::atomic_bool is_ready{}; is happening before either of the shown thread functions start execution.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文