阻塞队列就是多线程线程安全的队列,在多线程场景下经常用到,c++ 标准库里面没有提供阻塞队列,boost 中有提供,生成环境下可以使用

blocking queue 实现

主要设计思路:

  1. 使用 std::vector 实现一个环形队列,使用两个指针 start 和 end 来标识起止位置,push 的时候在 end 处插入,pop 的时候直接 start 指针往后移即可
  2. 使用 std::condition_variable 实现同步,push 的时候需要满足 _not_full 条件,push 完成发送 _not_empty 通知,pop 的时候需要满足 _not_empty 条件,pop 完成发送 _not_full 通知
template <typename T>
class BlockingQueue {std::mutex              _mutex;std::condition_variable _not_full;std::condition_variable _not_empty;int                     _start;int                     _end;int                     _capacity;std::vector<T>          _vt;public:BlockingQueue(const BlockingQueue<T>& other) = delete;BlockingQueue<T>& operator=(const BlockingQueue<T>& other) = delete;BlockingQueue(int capacity) : _capacity(capacity), _vt(capacity + 1), _start(0), _end(0) {}bool isempty() {return _end == _start;}bool isfull() {return (_start + _capacity - _end) % (_capacity + 1) == 0;}void push(const T& e) {std::unique_lock<std::mutex> lock(_mutex);while (isfull()) {_not_full.wait(lock);}_vt[_end++] = e;_end %= (_capacity + 1);_not_empty.notify_one();}T pop() {std::unique_lock<std::mutex> lock(_mutex);while (isempty()) {_not_empty.wait(lock);}auto res = _vt[_start++];_start %= (_capacity + 1);_not_full.notify_one();return res;}
};

生成者消费者

生成者线程不断往队列面插入一个随机数,消费者线程从队列里面取

void producer(BlockingQueue<int>& q, int i) {while (true) {std::random_device rd;auto               p = rd() % 10;q.push(p);std::cout << "produce " << i << " [" << p << "]" << std::endl;std::this_thread::sleep_for(std::chrono::milliseconds(1500 + rd() % 5000));}
}void consumer(BlockingQueue<int>& q, int i) {while (true) {std::random_device rd;auto               p = q.pop();std::cout << "consume " << i << " [" << p << "]" << std::endl;std::this_thread::sleep_for(std::chrono::milliseconds(1500 + rd() % 5000));}
}void producerConsumer() {BlockingQueue<int>       q(4);std::vector<std::thread> ps(10);std::vector<std::thread> cs(20);for (int i = 0; i < ps.size(); i++) {ps[i] = std::thread(producer, std::ref(q), i);}for (int i = 0; i < cs.size(); i++) {cs[i] = std::thread(consumer, std::ref(q), i);}for (int i = 0; i < ps.size(); i++) {ps[i].join();}for (int i = 0; i < ps.size(); i++) {cs[i].join();}
}

链接

  • 完整代码: https://github.com/hpifu/md-tech/blob/master/hatlonely/code/blocking-queue/blocking-queue.cpp

转载请注明出处
本文链接:https://tech.hatlonely.com/article/60

c++ 实现 blocking queue相关推荐

  1. Blocking Queue

    生产者和消费者的典型考题,用blocking queue来做. https://zhuanlan.zhihu.com/p/84647595 讲解 启发于:java 8 源代码:https://docs ...

  2. paddle报错SystemError: (Fatal) Blocking queue is killed because the data reader raises an exception.

    在使用paddle的dataloader的时候,如果def getitem(self, index):函数发生异常会报错: ERROR:root:DataLoader reader thread ra ...

  3. Paddle SystemError另一情况: (Fatal) Blocking queue is killed because the data reader raises an exception

    paddle框架(paddlepaddle版本时2.0.1)下在自定义的dataset上使用dataloader的时候,__getitem__(self, index):函数抛出异常会报错: File ...

  4. Handler实现与机制 Blocking Queue IdleHandler使用

    http://blog.csdn.net/boyupeng/article/details/46685343 IdleHandler处理消息的源码 final Message next() {.../ ...

  5. paddleOCR SystemError: (Fatal) Blocking queue is killed because the data reader raises an exception.

    百度了很久,看了很多博主的都没有解决问题/(ㄒoㄒ)/~~ 最后请教大佬,帮我解决了 第一可能是文件编码问题 问题1:UnicodeEncodeError: 'gbk' codec can't enc ...

  6. 干货 | 45张图庖丁解牛18种Queue,你知道几种?

    来源 | 悟空聊架构(ID:PassJava666) 在讲<21张图讲解集合的线程不安全>那一篇,我留了一个彩蛋,就是Queue(队列)还没有讲,这次我们重点来看看Java中的Queue家 ...

  7. Java queue总结

    1.LinkedBlockingQueue:基于链接节点的可选限定的blocking queue . 这个队列排列元素FIFO(先进先出). 队列的头部是队列中最长的元素. 队列的尾部是队列中最短时间 ...

  8. Creating a blocking QueueT in .NET

    Creating a blocking Queue<T> in .NET 这里的代码来自我们的StackOverflow 中的代码示例,我添加了一些中文注释: //there I will ...

  9. java多线程12:阻塞队列Queue

    本篇主要内容如下: 本篇主要内容 帮你总结好的阻塞队列: 18种Queue总结 一.Queue自我介绍 队列原理图 1.1 Queue自我介绍 hi,大家好,我的英文名叫Queue,中文名叫队列,无论 ...

最新文章

  1. Spring Cloud构建微服务架构(五)服务网关
  2. LabVIEW2015安装教程
  3. JRebel : java.lang.OutOfMemoryError: PermGen space 异常
  4. WildFly 8.0.0.Alpha1的发布和一些历史
  5. vc++ 6.0 堆栈_在C ++中使用链接列表实现堆栈
  6. 什么是Hyperledger?Linux如何围绕英特尔的区块链项目构建开放平台?
  7. screen,client,page三种确定鼠标坐标的区别和原生JS事件写法,区别于Jquery的$.on(x,y);和$.click()...
  8. 文本视图(UITextView)占位符Swift
  9. 1056 组合数的和 (15 分)—PAT (Basic Level) Practice (中文)
  10. shell中数组的使用
  11. 电脑文件夹同步软件哪个比较好用?
  12. 网络游戏植入广告的案例
  13. c语言删除元素1116,C语言网-1116题-IP判断
  14. 自然语言处理之——句法分析
  15. 续集来了:上回那个“吃鸡”成功的IC人后来发生了什么?
  16. el-table 表格展开与折叠
  17. vue h5适配ios刘海屏
  18. 立体匹配——A Large Dataset to Train Convolutional Networks for Disparity, Optical Flow, and Scene Flow Es
  19. java中公钥,私钥,pkcs1格式,pkcs8格式互转
  20. You are 87% Sagittarius

热门文章

  1. 赢在微点答案专区英语_成人高考@赢在技巧
  2. 三星a5000 android,三星a5000怎么样 三星a5000参数详解
  3. Spark知识点总结大全
  4. 面试官问我:View.post为什么能够获取View的宽高
  5. 04-python简单爬虫_爬取网易新闻
  6. Kinect体感机器人(二)—— 体感识别
  7. 论ERP顾问的创新分享与专业精神
  8. 2021年中国钻石粉末进出口情况分析:人工合成钻石粉末出口规模大幅增长[图]
  9. Qt5.9中设置QLabel控件边框线型(QSS实现:点画线、虚线、实线、3D边框)
  10. linux python urllib,Python urllib