我读到了这个问题的答案,关于易失性关键字:
https://stackoverflow.com/a/2485177/997112
此人说:
防止重新排序的解决方案是使用一个内存屏障,它向编译器和CPU指示,在这一点上不可能重新排序内存访问。在易失性变量访问周围设置这样的屏障,可以确保即使是非易失性访问也不会在易失性访问中被重新排序,从而允许我们编写线程安全代码。 然而,内存屏障也确保在达到障碍时执行所有挂起的读/写,因此它有效地为我们自己提供了我们所需要的一切,使易失性变得不必要。我们可以完全删除易失性限定符。
如何在C++中实现这个“内存屏障”?
编辑:
能给出一个简单的代码示例吗?
发布于 2013-07-27 17:12:49
在C++11中使用内存屏障非常简单:
std::atomic<int> i;所有对i的访问都将受到内存屏障的保护。
发布于 2013-07-27 13:36:39
这是非常依赖硬件的。来自Linux内核相当长的记忆屏障文件:
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")关于这两件事之间的差异的更多信息已经在这条线中讨论过了。我希望这能帮到你。
发布于 2013-07-27 19:06:44
通常,有“内在函数”--这些是编译器对它们的操作具有特殊知识的特殊函数(特别是它们是内存障碍)。名称因编译器而异(有时也适用于同一编译器的不同体系结构)。
例如,MSVC使用_ReadBarrier、WriteBarrier和_ReadWriteBarrier。
在x86中,它将产生一个lfence、sfence或mfence指令--它们分别执行“加载”、“存储”和“所有内存操作”屏障--换句话说,lfence将成为内存读取操作的障碍,sfence将成为“内存写入”屏障,mfence将成为读写操作的障碍。
https://stackoverflow.com/questions/17898140
复制相似问题