我有一个关于使用无锁队列的问题。
假设我有一个单生产者单消费者队列,其中生产者和消费者被绑定到不同的核心。队列元素是共享内存的缓冲区,生产者和消费者在开始时都会对其进行mmapped。
生产者获取一个队列元素,用数据填充缓冲区并将其入队,消费者将该元素出队,读取它并以某种方式处理它。
作为无锁队列的用户,我是否必须显式地确保生产者写入的缓冲区对用户可见?或者,算法核心的CAS (或其他类似的)原语会自动提供屏障吗?
我看到的几个示例使用整数作为有效负载,因此不会出现内存同步的问题。
谢谢,
发布于 2011-08-08 03:50:40
诸如比较和交换之类的互锁原语通常以具有不同内存屏障语义的变体出现。它们在不同的体系结构之间略有不同,但通常情况下,您希望(最迟)在生产者中的操作上具有“发布”语义,使结构对消费者可见,并在访问数据结构之前在消费者中具有“获取”语义。
在某些架构上(特别是普通的x86),您实际上没有选择的余地,因为每个互锁操作都意味着一个完全的屏障--但是如果这让您养成了不请求任何屏障的习惯,那么由于墨菲的原因,它就会在其他架构上咬您一口。
(相反,也是由于墨菲,如果您仔细研究这些选项并在各处插入正确的屏障,事件可能会合谋使您编写的任何代码只需要在x86上运行)。
发布于 2011-08-08 03:52:06
根据定义,这是特定于体系结构的。对于在英特尔CPU上的GCC来说,使用GCC Atomic Builins -大多数都意味着满内存屏障。
发布于 2011-08-09 10:02:50
一些归档文件将内存屏障绑定到CAS;x86/x64就是其中之一。
其他人(例如ARM)则不这样做。在ARM上,您执行LL/SC,在执行之前和之后都有一个手动的纯数据内存屏障。
https://stackoverflow.com/questions/6975263
复制相似问题