在原子上按释放内存顺序调用store后的notify_all方法



我有以下代码在一个线程上执行(用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调用重排在store之前,因为notify_all被指定为唤醒原子上所有等待有资格被解除阻塞的操作。

这取决于在原子的全局修改顺序中,发生的最后一个存储是否在之前,对notify_all的调用顺序是否在等待线程阻塞时观察到的存储之后。

在您所显示的代码中,true存储notify_all调用之前排序(在同一线程中),这意味着存储发生在调用之前,但是如果交换行,那么情况就不再是这样了。

notify_all移到store之前可能会改变等待操作的集合,这些操作有资格被解除阻塞

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

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

相关内容

  • 没有找到相关文章

最新更新