阻塞队列在存放获取队列中的数据时需要使用多线程,一个线程专门负责向队列中存放元素,另一个线程专门从队列中获取元素。也可多开辟跟多的线程进行存取。

规范的方法也正是存放获取队列元素分别在不同的线程中实现。

阻塞队列实现:

  1. 当队列为空时,从队列获取元素的操作将会被阻塞,直到队列中被放入了元素;

  2. 当队列满时,有两种方案:

  • 方案1: 往队列里存放元素的操作也会被阻塞,直到有元素被从队列中取出或者删除。
    具体方法:定义一个条件变量std::condition_variable not_full_;存放操作时,判断队列为满时,使用not_full_.wait(lock)阻塞线程;当进行删除队列元素的操作后,就使用not_full_.notify_all()来唤醒not_full_.wait(lock)的线程。

    注意区分: 条件变量not_empty_是在获取数据时判断队列是否为空,为空时,使用not_empty_.wait(lock); ,当有队列有新数据进来才会not_empty_.notify_all();唤醒not_empty_.wait(lock);的线程。 存放操作获取操作需要使用不同的条件变量进行阻塞等待和唤醒】

  • 方案2: 不使用阻塞,而是直接删除队列中最老的元素,删除后就直接往队列添加元素了。【本文示例就是方案2】

以上的操作都是基于不同的线程来说的,线程在对阻塞队列进程操作时会被阻塞。

#pragma once#include <condition_variable>
#include <deque>
#include <mutex>
#include <string>
#include <thread>
#include <list>
#include <vector>template <typename T>
class BlockingQueue {public:BlockingQueue(uint size) : size_(size) {}BlockingQueue() {}/*** @brief 向队列中push_back一个元素* **/void put(const T x) {std::unique_lock<std::mutex> lock(mutex_);if (size_ != 0 && queue_.size() > size_) {queue_.pop_front();}queue_.push_back(std::move(x));not_empty_.notify_all();  //有新数据push进来后就唤醒所有wait的线程}/*** @brief 获取队列中第一个元素(不是最新元素)* 元素一旦获取,就从队列中删除* **/T take() {std::unique_lock<std::mutex> lock(mutex_);while (queue_.empty()) {not_empty_.wait(lock);  //如果队列为空,线程就在此阻塞挂起,等待唤醒}const T front = queue_.front();queue_.pop_front();return front;}/*** @brief 取出队列中第一个元素(取出后就从队列中删除),并push_back到一个vector中* **/int take(std::vector<T> *v, size_t count) {std::unique_lock<std::mutex> lock(mutex_);while (queue_.empty()) {not_empty_.wait(lock);  //如果队列为空,线程就在此阻塞挂起,等待唤醒}while (!queue_.empty() && count--) {v->push_back(queue_.front());queue_.pop_front();}return v->size();}/*** @brief 根据索引获取队列中对应元素* **/T get(size_t index) {std::unique_lock<std::mutex> lock(mutex_);while (queue_.empty()) {not_empty_.wait(lock);}return queue_.at(index);}size_t size() const {std::unique_lock<std::mutex> lock(mutex_);return queue_.size();}private:mutable std::mutex mutex_;std::condition_variable not_empty_;std::deque<T> queue_;// std::list<T> queue_;//双向链表uint size_ = 0;
};

【多线程】阻塞队列的C++多线程 实现 BlockingQueue相关推荐

  1. java多线程-阻塞队列BlockingQueue

    大纲 BlockingQueue接口 ArrayBlockingQueue 一.BlockingQueue接口 public interface BlockingQueue<E> exte ...

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

    Queue是什么 队列,是一种数据结构.除了优先级队列和LIFO队列外,队列都是以FIFO(先进先出)的方式对各个元素进行排序的.无论使用哪种排序方式,队列的头都是调用remove()或poll()移 ...

  3. java多线程阻塞队列_阻塞队列和多线程消费者,如何知道何时停止

    我有一个单线程生成器,它创建一些任务对象,然后添加到 ArrayBlockingQueue (具有固定大小) . 我也开始了一个多线程的消费者 . 这是一个固定的线程池( Executors.newF ...

  4. 阻塞队列的应用 || 多线程的条件判断 一定要用while,而不要用 if

    ProdConsTradiDemo.java package thread;import java.util.concurrent.locks.Condition; import java.util. ...

  5. 一心多用多线程-阻塞队列(5)-CountDownLatch

    五.倒数执行机制-CountDownLatch Latch:门闩的意思.根据该类名的意思,我们就可以知道该类在多线中扮演的就是一个倒数门闩的角色,怎么理解呢? 首先呢,我们新建一个CountDownL ...

  6. 多线程 阻塞队列中的poll与take区别

    https://blog.csdn.net/qiuchaoxi/article/details/80359462

  7. 一心多用多线程-阻塞队列(7)-CyclicBarrier

    七.都做好了了就一起执行-CyclicBarrier 在文章(6)中我们谈到一个现象,就是做一道菜有时候是会分出多个工序进行的,当每个工序做好了之后那到菜才能相应的被做出来.文章(6)使用的是Coun ...

  8. Java多线程学习二十三:什么是阻塞队列

    阻塞队列的作用 阻塞队列,也就是 BlockingQueue,它是一个接口,如代码所示: public interface BlockingQueue<E> extends Queue&l ...

  9. Java并发包--阻塞队列(BlockingQueue)

    阻塞队列介绍 在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全"传输"数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质 ...

最新文章

  1. pytorch中网络loss传播和参数更新理解
  2. 网红送餐无人车被指用人冒充AI始末:没有人工,就没有智能
  3. python判断字符串中包含某个字符串_Python中最常用的字符串方法!
  4. 分割点云数据_3D点云深度学习综述:三维形状分类、目标检测与跟踪、点云分割等...
  5. python threading lock_python threading之死锁和可重入锁
  6. IOS开发学习记录第2天之熟悉Xcode常用快捷键
  7. 公共情报工具automater的基本使用
  8. 【英语学习】【WOTD】adversary 释义/词源/示例
  9. java 模板组件_9Tile模板和Tile组件创建复合式网页
  10. SI4463的数据冲撞解决办法【转】
  11. Nginx负载均衡配置实例详解(转发学习)留给未来需要的自己
  12. 视频演示SHAtter越狱iOS 4.1
  13. ppt画深度学习网络图
  14. Object.entries()
  15. tig只看某个作者的提交
  16. 我用最独特的方式为情人节准备了这些。。。
  17. 操作系统Topic推荐-AMiner
  18. 【C#】简繁体转换类
  19. Java SE 01 概述
  20. birthday中文是什么_birthday中文怎么读

热门文章

  1. 小白的消费为何被迫升级?-java数据类型的转换
  2. Sentinel 与 Hystrix、resilience4j 的对比
  3. spring源码分析之spring-jdbc模块详解
  4. Lesson 16.2 图像的基本操作
  5. 【风控模型】Logistic算法构建标准信用评分卡模型python代码案例
  6. 字节跳动(今日头条),为何战斗力如此凶猛?
  7. Gradient Boost 算法流程分析
  8. 高并发-【抢红包案例】之二:使用悲观锁方式修复红包超发的bug
  9. Spring-AOP 切点/切面类型和创建切面
  10. 复习(三)—— 进程管理详解