我正在使用boost :: lockfree :: queue Foo(128)。
在弹出队列之前,我可以通过Foo.empty()
函数检查队列的空状态。
我想知道是否可以在Pushing之前满负荷地检查其状态!在线找不到任何资源来解释如何做。
有什么建议吗?
答案 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()
的原因。