在c ++中是否有一个等待的队列?

时间:2017-06-13 12:14:42

标签: c++ multithreading concurrency task ppl

我在代码库中大量使用concurrency::task中的ppltasks.h

我想找到一个等待的队列,我可以在那里“co_await my_queue.pop()”。有人实施了吗?

详细说明: 我有一个生产者线程将元素推送到队列,另一个接收器线程将等待并在元素到达队列时唤醒。此接收线程可能会等待/唤醒以同时处理其他任务(使用pplpp :: when_any)。

我不想要一个带有接口的队列,我必须轮询try_pop方法,因为它很慢,而且我不想要一个blocking_pop方法,因为这意味着我不能在此期间处理其他准备好的任务。

2 个答案:

答案 0 :(得分:5)

这基本上是您的standard thread-safe queue implementation,但不是condition_variable,而是使用future来协调不同的主题。然后,您可以co_await pop返回由pop准备的未来。

队列的实现需要保留与未完成的pop调用相对应的承诺列表。如果std::mutex时队列仍然已满,您可以立即返回准备好的未来。您可以使用普通的旧condition_variable来同步对底层数据结构的并发访问。

我不知道已经执行过的任何实现,但它不应该太难实现。请注意,管理所有期货会带来一些额外的开销,因此您的队列可能会比基于Map的经典方法效率略低。

答案 1 :(得分:1)

发表评论但我不妨将其写为答案,因为我需要格式化。

基本上你有两个选择:

无锁队列,其中最受欢迎的是:

https://github.com/cameron314/concurrentqueue

他们确实有try_pop,因为它使用原子指针,任何原子方法(例如std :: atomic_compare_exchange_weak)都可以并且将会失败"并且有时返回false,因此您被迫对它们进行自旋锁定。

您可能会在" pop"中找到抽象的队列。只是打电话" try_pop"直到它起作用,但背景中的开销相同。

基于锁定的队列:

这些更容易自己做,没有第三部分库,只需要在锁中包装你需要的每一种方法,如果你想偷看'经常考虑使用shared_locks,否则只需要std :: lock_guard就足以保护所有包装器。然而,这就是你可以称之为“阻止”的东西。队列,因为在访问期间,天气是读取或写入,整个队列将被锁定。

这两种实现没有线程安全的替代方案。如果你需要一个非常大的队列(例如数百GB的内存对象),你可以考虑编写一些自定义的混合数据结构,但对于大多数用例来说,moodycamel的队列将是绰绰有余的