c++ - 重新排序原子读取

标签 c++ multithreading concurrency atomic

我正在研究读取两个共享原子变量的多线程算法:

std::atomic<int> a(10);
std::atomic<int> b(20);

void func(int key) {
   int b_local = b;
   int a_local = a;
   /* Some Operations on a & b*/
}

该算法的不变量是b应该在读取a之前读取。

问题是,编译器(比如 GCC)能否重新排序指令,以便在 b 之前读取 a?使用显式内存栅栏可以实现这一点,但我想了解的是,两个原子负载是否可以重新排序。

此外,在了解了 Herb Sutter 的演讲(http://herbsutter.com/2013/02/11/atomic-weapons-the-c-memory-model-and-modern-hardware/)中的获取/释放语义之后,我了解到顺序一致的系统可确保获取(如加载)和释放(如存储)之间的顺序。如何在两次获取(如两次加载)之间进行排序?

编辑:添加有关代码的更多信息: 考虑两个线程 T1 和 T2 执行:

T1:读取b的值,休眠

T2:改变a的值,返回

T1 : 唤醒并读取a的新值(new value)

现在,考虑重新排序的场景:

int a_local =a; int b_local = b;

T1:读取a的值,休眠

T2:改变a的值,返回

T1:对 a 值的变化一无所知。

问题是“像 GCC 这样的编译器能否重新排序两个原子加载”

最佳答案

Descriptionmemory_order_acquire :

no memory accesses in the current thread can be reordered before this load.

作为加载时的默认内存顺序bmemory_order_seq_cst ,这是最强的,阅读自a在读取 b 之前无法重新排序.

甚至更弱的内存顺序,如以下代码所示,也提供相同的保证:

int b_local = b.load(std::memory_order_acquire);
int a_local = a.load(std::memory_order_relaxed);

关于c++ - 重新排序原子读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34554587/

相关文章:

c++ - Visual Studio 中的 "Create Precompiled Header"(/Yc) 和 "Use Precompiled Header"(/Yu) 有什么区别?

c++ - 使用 C++ 和 Linux 写入文件

c - C 中的多参数 pthread_create() 函数?

c++ - 多线程访问全局变量: should I use mutex

遍历文件夹时 Goroutine 死锁

java - 比较并设置预期时的内存效果==更新

c++ - 冰淇淋店的字符串程序(再次编辑)

c++ - 如何停止 wxProgressDialog 重新调整大小?

java - 在Java中为pdf设置计时器并在计时器用完后关闭它

python - 将 concurrent.futures.Future 与 greenlets/gevent 一起使用