Fast C ++单一生产者单一消费者实现

时间:2011-07-09 22:25:12

标签: c++ performance producer-consumer

我正在寻找单一生产者,单用户FIFO实现,其执行速度比普通的lock-write-unlock-signal / waitForSignal-lock-read-unlock更快。我正在寻找用C或C ++编写的大多数POSIX操作系统支持的东西(特定于x86)。

我不想传递任何大于指针的东西。

我不一定依赖于无锁的想法,但我确实想要快速和正确的东西。我在这个主题上读到的一篇论文提到了一个看起来很有趣的双队列方法,但从那时起我就无法找到很多相关内容。

从我迄今为止所做的研究来看,0mq(据说它的inproc://方案使用无锁结构)看起来像是最吸引人的选择。话虽如此,我想确保在走这条路之前我没有错过任何事情。

另一个替代方案可能涉及使用POSIX消息队列,但这似乎对于线程< - >而言相当慢。线程通信;这是真的吗?

Any single-consumer single-producer lock free queue implementation in C?似乎是相关的,但是接受的答案实际上并不是现有库的枚举,而是“过早优化是坏事”。

4 个答案:

答案 0 :(得分:2)

您将需要查看英特尔的线程构建模块。它们构建于x86的用户模式原子操作,pthreads或Win32线程提供的原语之上,并提供快速,高效,模板化的数据结构。并发队列就是其中之一。

答案 1 :(得分:1)

今晚偶然发现了CDS (Concurrent Data Structures)

  

CDS(并发数据结构)是一种无锁和细粒度算法的C ++模板库。它包含一组并发数据结构:队列,地图,危险指针回收模式,以及许多其他数据

我必须说我只是稍微过了/得到它来构建/舞台(它不像我喜欢的那样简单)但是......你可能有兴趣自己去看看。 / p>

答案 2 :(得分:1)

问题是POSIX没有包含用于互锁操作的API(我知道)。事实上,并非所有平台都支持无锁编程的相同操作(有些使用比较和交换,有些使用load-linked-store-conditional)。

也就是说,制作无锁单用户队列(支持多个生产者)的唯一困难部分是处理ABA问题,这真的应该不是问题。

您需要一个单独链接列表供生产者添加(前置)。消费者有一个本地队列,当它耗尽时,它会抓取整个生产者列表并将其反转,从而创建一个新的本地队列。 Windows SList API就是一个例子。

答案 3 :(得分:1)

除了这里的其他答案(以及此highly related question)之外,我将借此机会对my own超级快速,单一消费者单一的C ++实施进行无耻的插件 - 生产者等待队列。它:

  • 使用C ++ 11移动语义
  • 根据需要增长(但只有在你想要的时候)
  • 对元素进行无锁内存管理(使用预先分配的连续块)
  • 是独立的(两个标题加上许可证和自述文件)
  • 在MSVC2010 +,Intel ICC 13和GCC 4.7.2下编译(并且应该在任何C ++ 11完全兼容的编译器下工作)

根据简化的BSD许可证available on GitHub(随意分叉!)。

一个可比较的队列是Facebook's Folly queue,它可以稍微快一点,但不支持根据需要增长(它有固定的大小)。