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

Can a boost::lockfree::queue be checked for full?

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

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

我想知道我是否可以在推送之前以类似的方式检查其满负荷状态!在网上找不到任何资源来解释如何操作。

有什么建议吗?

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

boost::lockfree::spsc_queue(单生产者单消费者环形缓冲区队列)确实如此,spsc.write_available() > 0.


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

为了性能,您可能应该将其设置为固定大小。或者如果你想限制动态分配,你可以使用 bounded_push 而不是 push,这样它将 return false 而不是去 OS 以获得更多内存(这可能不是无锁的)。


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

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

(此外,消费者可能会在您检查后立即使队列未满,因此只有在尝试推送时进行检查才有意义。也许甚至没有一种有效的无锁方式检查。否则他们可以让函数总是 return 对于非固定大小的队列为真,并且 return 对于固定大小的队列是有意义的结果。)

这就是为什么push() returns boolfalse表示队列已满(或新节点无法为非固定大小的队列分配。


Before Popping the queue I can check the queue for empty status by Foo.empty() function.

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

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

不兼容

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