我正在阅读有关volatile关键字的问题的答案:
https://stackoverflow.com/a/2485177/997112
该人说:
防止重新排序的解决方案是使用内存屏障, 这表示编译器和CPU都没有内存访问 可以在这一点重新排序。在我们的周围放置这样的障碍 volatile变量访问确保即使是非易失性访问也不会 在volatile中重新排序,允许我们编写线程安全的 代码。
但是,内存障碍还可以确保所有挂起的读/写都是 到达障碍时执行,所以它有效地给了我们 我们需要的一切,不必要的挥发性。我们可以 完全删除volatile限定符。
这个“内存障碍”如何在C ++中实现?
编辑:
有人可以提供一个简单的代码示例吗?
答案 0 :(得分:6)
这非常依赖于硬件。来自Linux内核的相当长的documentation of memory barrier:
The Linux kernel has eight basic CPU memory barriers:
TYPE MANDATORY SMP CONDITIONAL
=============== ======================= ===========================
GENERAL mb() smp_mb()
WRITE wmb() smp_wmb()
READ rmb() smp_rmb()
DATA DEPENDENCY read_barrier_depends() smp_read_barrier_depends()
让我们特别考虑其中一个:smp_mb()
。
如果您打开asm/x86/um/asm/barrier.h
,则会在定义CONFIG_SMP
时发现
#define smp_mb() mb()
如果你向上滚动,你可以看到,根据平台,mb有不同的实现:
// on x86-32
#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2)
// on other platforms
#define mb() asm volatile("mfence" : : : "memory")
this thread讨论了有关这两件事之间差异的更多信息。我希望这会有所帮助。
答案 1 :(得分:6)
在C ++ 11中使用内存障碍是微不足道的:
std::atomic<int> i;
对i
的所有访问都将受到内存障碍的保护。