阻塞队列和非阻塞队列

Posted

技术标签:

【中文标题】阻塞队列和非阻塞队列【英文标题】:Both blocking and non blocking queue 【发布时间】:2014-10-16 20:43:06 【问题描述】:

我需要建立一个生产者-消费者方案,其中两个线程通过队列链接(生产者将任务推入队列,消费者在它们到来时执行它们)。

由于队列大部分时间都是空的,所以我必须让消费者线程可以休眠并在生产者推送某些内容时立即被唤醒。但是,我必须确保生产者永远不会被阻止,即使是短期内也不会。换句话说,我需要一些单边阻塞队列。

有无锁队列,但由于它们的定义是无锁的,消费者线程不可能被它们阻塞。

我曾想过将无锁队列与条件变量相关联。当消费者线程发现队列为空时,它会休眠等待通知条件。生产者线程将在将任务推送到队列中唤醒消费者线程(如果它正在休眠)时通知条件。但是,条件变量必须由互斥锁保护,这意味着生产者线程在尝试获取它以通知条件时仍然有很小的机会被阻塞。

我还没有找到解决这个问题的好方法,所以欢迎你的想法。

注意:我打算使用 boost 线程来实现这一点。

注意 2:我没有考虑生产者尝试推送某些东西并且队列已满的情况。这永远不会发生。

【问题讨论】:

boost lockfree queues 可以被阻塞,你可以使用它。 Fwiw,cvar/mtx 对中的互斥锁不是为了保护条件变量;这是为了保护谓词数据。值得一提的是,生产者无需在发出 cvar 信号之前锁定互斥锁。您的谓词状态(队列条件)是无锁的。消费者显然需要在醒来后立即解锁互斥锁,但这实际上就是它的全部内容。 生产者想发帖但队列已满,怎么办? @quantdev :据我从文档中得知,boost::lockfree::spsc_queue 和 boost::lockfree::queue pod() 方法都会立即返回,无论是否弹出或不是。所以我看不出如何用这些阻塞消费者线程。我是不是误会了什么? @MaximYegorushkin :我认为这种情况永远不会发生。 【参考方案1】:

tbb library provides 阻塞和非阻塞队列:

tbb::concurrent_queue<> 提供非阻塞 try_pop()push() 以实现无限增长。 tbb::concurrent_bounded_queue<> 提供push(),如果指定了容量限制并且达到了它,它可以阻塞;和 pop() 等待空队列中的项目。它还为同一队列提供非阻塞 try_push()try_pop() 替代方案。

【讨论】:

我认为 OP 需要一个支持阻塞和非阻塞操作的单一数据结构

以上是关于阻塞队列和非阻塞队列的主要内容,如果未能解决你的问题,请参考以下文章

阻塞队列

java 多线程阻塞队列 与 阻塞方法与和非阻塞方法

嵌入式Linux开发27——Linux阻塞和非阻塞IO

阻塞队列--概述

线程队列之阻塞队列LinkedBlockingQueue

什么是阻塞队列?如何使用阻塞队列来实现生产者-消费者模型?