简体   繁体   English

为什么concurrent_queue是非阻塞的?

[英]why is concurrent_queue non-blocking?

In the concurrency runtime introduced in VS2010, there is a concurrent_queue class. 在VS2010中引入的并发运行时中,有一个concurrent_queue类。 It has a non blocking try_pop() function. 它有一个非阻塞的try_pop()函数。
Similar in Intel Thread Building Blocks (TBB), the blocking pop() call was removed when going from version 2.1 to 2.2. 类似于英特尔线程构建模块(TBB),从版本2.1到2.2时,阻止pop()调用被删除。

I wonder what the problem is with a blocking call. 我想知道阻塞调用的问题是什么。 Why was it removed from TBB? 为什么要从TBB中删除? And why is there no blocking concurrent_queue? 为什么没有阻塞concurrent_queue?

I'm in a situation where I need a blocking concurrent queue, and I don't want a busy wait. 我正处于需要阻塞并发队列的情况,我不想忙碌等待。 Apart from writing a queue myself, is there another possibility in the concurrency runtime? 除了自己编写队列之外,并发运行时还有另一种可能吗?

From a comment from Arch Robison , and it doesn't get much more "horse's mouth" than that (a) : 来自Arch Robison的评论 ,并没有比(a)更多的“马口”


PPL's concurrent_queue has no blocking pop, hence neither does tbb::strict_ppl::concurrent_queue . PPL的concurrent_queue没有阻塞弹出,因此tbb::strict_ppl::concurrent_queue也没有。 The blocking pop is available in tbb::concurrent_bounded_queue . 阻止弹出在tbb::concurrent_bounded_queue可用。

The design argument for omitting blocking pop is that in many cases, the synchronization for blocking is provided outside of the queue, in which case the implementation of blocking inside the queue becomes unnecessary overhead. 省略阻塞弹出的设计参数是,在许多情况下,阻塞的同步是在队列外部提供的,在这种情况下,队列内部阻塞的实现变得不必要。

On the other hand, the blocking pop of the old tbb::concurrent_queue was popular among users who did not have outside synchronization. 另一方面,旧tbb::concurrent_queue的阻塞弹出在没有外部同步的用户中很流行。

So we split the functionality. 所以我们分开了功能。 Use cases that do not need blocking or boundedness can use the new tbb::concurrent_queue , and use cases that do need it can use tbb::concurrent_bounded_queue . 不需要阻塞或有界的用例可以使用新的tbb::concurrent_queue ,而需要它的用例可以使用tbb::concurrent_bounded_queue


(a) Arch is the architect of Threading Building Blocks. (a) Arch是线程构建模块的架构师。

If you need a blocking pop without a busy wait, you need a method of signaling. 如果您需要阻塞弹出而没有繁忙的等待,则需要一种信令方法。 This implies synchronization between pusher and poper and the queue is no longer without (expensive) synchronization primitives. 这意味着推送器和poper之间的同步,并且队列不再没有(昂贵的)同步原语。 You basically get a normal synchronized queue with a condition variable being used to notify poppers of pushes, which is not in the spirity of the concurrent_* collections. 您基本上可以获得一个正常的同步队列,其中一个条件变量用于通知poppers的push,这不在concurrent_ *集合的spirity中。

The question was if there was another option in the Concurrency Runtime that provides blocking queue functionality because concurrent_queue does not and there is one in VS2010. 问题是并发运行时是否有另一个选项提供阻塞队列功能,因为concurrent_queue没有,VS2010中有一个。

Arch's comment is of course completely correct, blocking queues and unblocking queues are separate use cases and this is why they are different in VS2010 and in TBB. Arch的注释当然是完全正确的,阻塞队列和解除阻塞队列是单独的用例,这就是它们在VS2010和TBB中不同的原因。

In VS2010 you can use the template class unbounded_buffer located in , the appropriate methods are called enqueue and dequeue. 在VS2010中你可以使用位于其中的模板类unbounded_buffer,相应的方法称为enqueue和dequeue。

-Rick -Rick

There is no situation, from the queue's standpoint, that it should need to block for an insert or remove. 从队列的角度来看,没有任何情况需要阻止插入或移除。 The fact that you may need to block and wait for an insert is immaterial. 您可能需要阻止并等待插入的事实并不重要。

You can achieve the functionality you desire by using a condition variable, or a counting semaphore, or something along those lines (whatever your specific API provides). 您可以通过使用条件变量或计数信号量或类似的东西(无论您的特定API提供)来实现您所需的功能。 Your trouble isn't with blocking/non-blocking; 你的麻烦不在阻塞/非阻塞; it sounds like a classic producer-consumer. 它听起来像一个经典的生产者 - 消费者。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM