使用boost::lockfree::spsc_queue时需要内存屏障吗?

5
我正在查看Boost的无锁队列
当生产者线程将数据结构T推入缓冲区时,它会通过复制构造函数复制到缓冲区中。
当消费者线程尝试调用consume_one()来读取缓冲区中的元素时,似乎需要内存屏障?如果不是这样,那么生产者线程所做的更改如何对消费者线程可见?
谢谢!
1个回答

5

不需要额外的内存屏障。

队列使用内存顺序获取读取索引,使用内存顺序释放写入索引:http://en.cppreference.com/w/cpp/atomic/memory_order

  • 获取:具有此内存顺序的加载操作执行对所影响的内存位置的获取操作:由执行释放操作的线程在另一个内存位置进行的先前写入在该线程中变为可见。
  • 释放:具有此内存顺序的存储操作执行释放操作:先前对其他内存位置的写入对在同一位置上执行消耗或获取的线程变得可见。

正如您所看到的,实际元素数据的写入也不需要担心,因为索引更新(在复制后完成)发生在读取之前。


由于使用SPSC队列的文档要求明确指出,消费者和生产者始终是相同的单个线程,因此所有“本地”索引操作都使用“松散”的内存顺序进行。

请注意,唯一与此不同的操作是reset(),它类似于构造/析构,不是线程安全的。

有关内存顺序的背景知识,我推荐Anthony William的优秀书籍C++ Concurrency In Action


1
@Hei,FYI,他们最近修复了一个bug;看起来这个问题不仅仅是文档的问题:https://github.com/boostorg/lockfree/commit/f7bb4d14022426fa5c6affc5f5970ecbe855d061(据我所知,这个修复还没有在任何发布版本中) - sehe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接