c++ - 在原子上存储并释放内存顺序后调用notify_all方法

标签 c++ multithreading atomic c++20 stdatomic

我在单个线程上执行以下代码(用 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);
}

据我所知,释放内存顺序并不能确保位于其之后的操作不会被编译器重新排序。那么,我可以将 notify_all() 放在 store() 之后并按释放内存顺序吗?安全吗?只是我有一些想法,store() 可能会在 notify_all() 之前排序,因此可能不会重新排序。

最佳答案

内存顺序在这里无关紧要。它们仅影响内存访问的顺序,除了原子本身之外,而您没有任何影响。

在任何情况下,编译器都无法在存储之前重新排序 notify_all 调用,因为 notify_all is specified唤醒原子上的所有等待操作 eligible to be unblocked .

这些取决于是否在global modification order中原子的最后一个存储 happens-beforenotify_all 的调用是在等待线程阻塞时观察到的存储之后排序的。

在您显示的代码中,true 存储为 sequenced-before notify_all 调用(在同一个线程中),这意味着存储发生在调用之前,但如果线路被切换,那么情况就不会是这样不再了。

notify_all 移到存储之前可能会更改有资格解锁的等待操作集。

如果允许编译器这样做,那么等待/通知机制将毫无用处。这也与同一线程中同一原子上的其他操作(或者同一线程中同一存储位置上的任何操作)相同。编译器也无法对它们重新排序。

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

关于c++ - 在原子上存储并释放内存顺序后调用notify_all方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72670980/

相关文章:

php 扩展如何从一个方法返回一个字符串?

java - 与 Netty 一起使用时 Camel ServicePool 背后的逻辑

c++ - 列表初始化是否将原子初始化为零?

c++ - C++ 11 标准是否保证 std::atomic<> 被实现为无锁操作?

c++ - 分配 vector 值

c++ - 指向模板抽象类的指针 vector ?

C++ - 通过基于元素的自定义键搜索 vector

java - 字段的默认值是否保证在线程中可见?

c# - ASP.NET 真正的异步操作

objective-c - 哪个是线程安全的原子或非原子?