是否可以检查boost :: lockfree :: queue是否已满?

时间:2019-03-28 10:13:20

标签: c++ boost queue lock-free

我正在使用boost :: lockfree :: queue Foo(128)。

在弹出队列之前,我可以通过Foo.empty()函数检查队列的空状态。

我想知道是否可以在Pushing之前满负荷地检查其状态!在线找不到任何资源来解释如何做。

有什么建议吗?

1 个答案:

答案 0 :(得分:1)

Boost的LF多生产者多消费者queue实现似乎不支持此功能。其他MPMC队列也可能。

boost::lockfree::spsc_queue(单生产者单消费者环形缓冲区队列)使用spsc.write_available() > 0


boost::lockfree::queue is not fixed-size by default,仅当您通过容量作为模板arg或fixed_sized<true>时。 如果将数据结构配置为固定大小,则内部节点将存储在数组中,并通过数组索引对其进行寻址。(但它不像某些其他MPMC队列那样是环形缓冲区。)否则它们是动态分配的,并保留在空闲列表中。

为了提高性能,您可能应该将其设置为固定大小。或者,如果您想限制动态分配,则可以使用bounded_push而不是push,这样它将返回false而不是进入操作系统以获取更多的内存(这可能不是无锁的)。 / p>


如果您使用的是queue<fixed_size<true>>,则 队列已满。

但是单独检查并没有太大意义,因为另一个生产者可能使检查和推送之间的队列已满。您是否正在寻找一种性能优化方法,例如如果准备好调用push时队列可能仍然已满,则避免构造对象?

(此外,使用者可以在检查后立即使队列不满,因此在尝试进行推送的过程中真正检查才有意义。也许甚至没有一种有效的无锁检查方法否则,该函数可能对于非固定大小的队列总是返回true,而对于固定大小的队列则返回有意义的结果。)

这就是push()返回bool的原因:false表示队列已满(或无法为非固定节点分配新节点,大小队列)。


  

在弹出队列之前,我可以通过Foo.empty()函数检查队列的空状态。

我希望您实际上并没有这样做;与push一样,与其他线程竞争同样存在问题,并且优化的机会更少。尝试之前没有要构造的对象,您只需调用pop并查看是否得到一个对象。

在检查和实际弹出之间,另一个线程可能使队列为空,或者使队列为非空。除非您是唯一的消费者,否则在这种情况下看到非空确实意味着您可以弹出。多生产者单消费者用例将与spsc_queue不兼容。

无论如何,这就是为什么它是bool pop(T &);而不是T pop()的原因。