【问题标题】:Can a boost::lockfree::queue be checked for full?可以检查 boost::lockfree::queue 是否已满?
【发布时间】:2019-03-28 10:13:20
【问题描述】:

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

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

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

有什么建议吗?

【问题讨论】:

    标签: c++ boost queue lock-free


    【解决方案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而不是去操作系统获取更多内存(可能不是无锁的)。


    如果您使用的是queue<fixed_size<true>>,那么队列有可能变满。

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

    (此外,消费者可能会在您检查后立即使队列未满,因此仅将检查作为尝试推送的一部分才有意义。也许甚至没有一种有效的无锁检查方式. 否则,他们可以让函数始终为非固定大小的队列返回 true,并为固定大小的队列返回有意义的结果。)

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


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

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

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

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

    【讨论】:

    • 这是一个精心起草的答案。谢谢:)
    猜你喜欢
    • 2015-06-22
    • 2013-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-28
    • 1970-01-01
    • 2013-07-01
    相关资源
    最近更新 更多