我在单个线程上执行以下代码(用 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-before对 notify_all
的调用是在等待线程阻塞时观察到的存储之后排序的。
在您显示的代码中,true
存储为 sequenced-before notify_all
调用(在同一个线程中),这意味着存储发生在调用之前,但如果线路被切换,那么情况就不会是这样不再了。
将 notify_all
移到存储之前可能会更改有资格解锁的等待操作集。
如果允许编译器这样做,那么等待/通知机制将毫无用处。这也与同一线程中同一原子上的其他操作(或者同一线程中同一存储位置上的任何操作)相同。编译器也无法对它们重新排序。
所以是的,它是安全的,Wait
线程不会永远等待。 (我假设初始化 std::atomic_bool is_ready{};
发生在所示线程函数开始执行之前。)
关于c++ - 在原子上存储并释放内存顺序后调用notify_all方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72670980/