为什么concurrent_queue是非阻塞的?

时间:2010-10-13 14:36:40

标签: c++ concurrency queue

在VS2010中引入的并发运行时,有一个concurrent_queue类。它具有非阻塞的try_pop()函数 类似于英特尔线程构建模块(TBB),从版本2.1到2.2时,阻止pop()调用被删除。

我想知道阻塞调用的问题是什么。为什么要从TBB中删除?为什么没有阻塞concurrent_queue?

我处在需要阻塞并发队列的情况下,我不想忙碌等待。 除了自己编写队列之外,并发运行时还有另一种可能吗?

4 个答案:

答案 0 :(得分:26)

来自a comment from Arch Robison,并且它比{sup>(a):

更多"horse's mouth"

PPL的concurrent_queue没有阻止弹出,因此tbb::strict_ppl::concurrent_queue也没有。阻止弹出式文件位于tbb::concurrent_bounded_queue

省略阻塞弹出的设计参数是,在许多情况下,阻塞的同步是在队列外部提供的,在这种情况下,队列内部阻塞的实现变得不必要。

另一方面,旧tbb::concurrent_queue的阻止弹出广告在没有外部同步的用户中很受欢迎。

所以我们分开了功能。不需要阻止或有限的用例可以使用新的tbb::concurrent_queue,而需要它的用例可以使用tbb::concurrent_bounded_queue


(a) Arch是线程构建模块的架构师。

答案 1 :(得分:4)

如果您需要阻止弹出而没有繁忙的等待,则需要一种信令方法。这意味着推送器和poper之间的同步,并且队列不再没有(昂贵的)同步原语。您基本上得到一个正常的同步队列,其中一个条件变量用于通知poppers的推送,这不在concurrent_ *集合的精神中。

答案 2 :(得分:2)

问题是并发运行时是否有另一个选项提供阻塞队列功能,因为concurrent_queue没有,VS2010中有一个。

Arch的评论当然是完全正确的,阻塞队列和解除阻塞队列是单独的用例,这就是VS2010和TBB中它们不同的原因。

在VS2010中你可以使用位于其中的模板类unbounded_buffer,相应的方法称为enqueue和dequeue。

-Rick

答案 3 :(得分:0)

从队列的角度来看,没有任何情况应该需要来阻止插入或删除。您可能需要阻止并等待插入这一事实并不重要。

您可以通过使用条件变量或计数信号量或类似的东西(无论您的特定API提供什么)来实现您所需的功能。你的麻烦不在阻塞/非阻塞;它听起来像一个经典的生产者 - 消费者。