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

时间:2014-10-26 09:50:42

标签: multithreading c++11 boost g++ lock-free

我在看Boost's lockfree queue

当生产者线程将数据结构T推入缓冲区时,它会(通过复制构造函数)复制到缓冲区中。

当消费者线程试图调用consume_one()来读取缓冲区中的元素时,似乎需要一个内存屏障?如果没有,那么生产者线程所做的更改怎么可能对消费者线程可见?

谢谢!

1 个答案:

答案 0 :(得分:4)

不需要额外的内存屏障。

当使用内存顺序 acquire 读取索引时,队列正常工作,并使用 release 内存顺序写入:http://en.cppreference.com/w/cpp/atomic/memory_order

  • 获取:使用此内存顺序的加载操作会对受影响的内存位置执行获取操作:执行发布的线程先前对其他内存位置的写入在此线程中可见。< / LI>
  • 发布:具有此内存顺序的存储操作会执行释放操作:先前对其他内存位置的写入对在同一位置执行使用或获取的线程可见

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


由于使用SPSC队列的文档要求清楚地表明消费者和生产者将始终是相同的,单一的线程,所有“本地”索引操作都是通过“放松”的内存顺序完成的。

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

对于记忆顺序的背景,我推荐Anthony William的优秀书C++ Concurrency In Action