c++阻塞队列

基于C++11的阻塞队列简单实现

     转载请说明出处:http://blog.csdn.net/cywosp/article/details/9157379

     在多线程编程中阻塞队列(Blocking Queue)是一种常用于实现生产者和消费者模型的数据结构。其与普通的队列区别在于,当队列为空时,从队列获取元素的操作将会被阻塞,直到队列中被放入了元素;当队列满时,往队列里存放元素的操作也会被阻塞,直到有元素被从队列中取出(以上的操作都是基于不同的线程来说的,线程在对阻塞队列进程操作时会被阻塞)。下图展示如何通过阻塞队列来合作:

                             

接下来我们用C++11来实现一个简单的阻塞队列(没有容量限制的BlockingQueue)

[cpp] view plaincopy
  1. template<typename T>  
  2. class BlockingQueue  
  3. {  
  4. public:  
  5.     BlockingQueue () : _mutex (), _condvar (), _queue ()  
  6.     {  
  7.   
  8.     }  
  9.   
  10.     void Put (const T& task)  
  11.     {  
  12.         {  
  13.             std::lock_guard<std::mutex> lock (_mutex);  
  14.             _queue.push_back (task);  
  15.         }  
  16.         _condvar.notify_all ();  
  17.     }  
  18.   
  19.     T Take ()  
  20.     {  
  21.         std::unique_lock<std::mutex> lock (_mutex);  
  22.         _condvar.wait (lock, [this]{return !_queue.empty ();});  
  23.         assert (!_queue.empty ());  
  24.         T front (_queue.front ());  
  25.         _queue.pop_front ();  
  26.   
  27.         return front;  
  28.     }  
  29.   
  30.     size_t Size() const  
  31.     {  
  32.         std::lock_guard<std::mutex> lock (_mutex);  
  33.         return _queue.size();  
  34.     }  
  35.   
  36. private:  
  37.     BlockingQueue (const BlockingQueue& rhs);  
  38.     BlockingQueue& operator = (const BlockingQueue& rhs);  
  39.   
  40. private:  
  41.     mutable std::mutex _mutex;  
  42.     std::condition_variable _condvar;  
  43.     std::list<T> _queue;  
  44. };  

注:以上代码需要加入下列头文件
#include <condition_variable>
#include <list>
#include <assert.h>
编译时需要加入编译选项 -std=c++0x或者-std=c++11
简单测试程序如下:
将上述代码放到 BlockingQueue.hpp文件中
[cpp] view plaincopy
  1. #include <iostream>  
  2. #include <thread>  
  3. #include <future>  
  4. #include "BlockingQueue.hpp"  
  5.   
  6. int main (int argc, char* argv[])  
  7. {  
  8.     BlockingQueue<int> q;  
  9.     auto t1 = std::async (std::launch::async, [&q] () {  
  10.         for (int i = 0; i < 10; ++i) {  
  11.             q.Put (i);  
  12.         }  
  13.     });  
  14.   
  15.     auto t2 = std::async (std::launch::async, [&q] () {  
  16.         while (q.Size ()) {  
  17.             std::cout << q.Take () << std::endl;  
  18.         }  
  19.     });  
  20.   
  21.     auto t3 = std::async (std::launch::async, [&q] () {  
  22.         while (q.Size ()) {  
  23.             std::cout << q.Take () << std::endl;  
  24.         }  
  25.     });  
  26.   
  27.     t1.wait ();  
  28.     t2.wait ();  
  29.     t3.wait ();  
  30.   
  31.     return 0;  
  32. }  
编译: g++ -o blockingqueue -std=c++11 main.cpp BlockingQueue.hpp -pthread
执行blockingqueue得如下结果:
10

23
4
5
6
7
8
9
本篇文章只是简单的实现了阻塞队列的插入函数与获取函数,在java中有线程的BlockingQueue容器可以直接使用,其提供了很多有用的函数(欲知请Google)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/509655.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java中ArrayList类的操作

ArrayList类是Java集合框架出现之后用来取代Vector类的: 二者底层原理都是基于数组的算法,一模一样. 区别: Vector: 所有的方法都使用了synchronized修饰符. 线程安全但是性能较低. 适用于多线程环境. ArrayList:所有的方法都没有使用synchronized修饰符. 线程不安全但是性…

Elasticsearch Painless Script详解

文章目录1. Painless 简介Painless 的用途2. 参数3. 首选参数4. 简短脚本形式5. 通过 Painless 脚本访问字段6. 示例6.1 案例 1&#xff1a;Script Processsor6.2 案例 2&#xff1a;文档更新计数6.3 案例 3&#xff1a;搜索时的 Script 字段6.4 Script :Inline v.s Stored6.5 …

Reactor事件驱动的两种设计实现:面向对象 VS 函数式编程

内容目录&#xff1a; Reactor实现架构对比面向对象的Reactor方案设计函数式编程的Reactor设计示例对比两者的时序图对比结论 Reactor事件驱动的两种设计实现&#xff1a;面向对象 VS 函数式编程 这里的函数式编程的设计以muduo为例进行对比说明&#xff1b; Reactor实现架构对…

ElasticSearch 快照 备份、恢复数据

文章目录ElasticSearch 设置备份文件地址注册快照存储库查看快照存储库保存结果创建快照异步创建指定索引进行快照查看全部快照在服务器查看备份的数据恢复数据本机恢复其他服务器恢复常见问题报错 doesnt match any of the locations specified by path.repo because this set…

java中LinkedList类的操作

LinkedList类是双向链表,单向队列,双向队列,栈的实现类: LinkedList类实现单向队列和双向队列的接口,自身提高了栈操作的方法,链表操作的方法. 在LinkedList类中存在很多方法,但是功能都是相同的.LinkedList表示了多种数据结构的实现,每一种数据结构的操作名字不同. 面试题:编…

FileBeat + Pipeline 解析日志 保存至ElasticSearch(实战)

文章目录FileBeat Pipeline 解析日志 保存至ElasticSearch&#xff08;实战&#xff09;下载地址目的日志数据模拟Pipeline创建pipeline查看Pipeline是否创建成功创建FileBeat配置文件 filebeat.yml创建自定义字段 FileBeat fields.yml执行 FileBeatfilebeat 启动命令说明测试…

网络编程中的关键问题总结

内容目录&#xff1a; 连接建立连接断开消息到达发送消息消息发送完毕其它问题参考 网络编程中的关键问题总结 总结下网络编程中关键的细节问题&#xff0c;包含连接建立、连接断开、消息到达、发送消息等等&#xff1b; 连接建立 包括服务端接受 (accept) 新连接和客户端成功发…

List实现类性能和特点分析

面向接口编程: 接口类型 变量 new 实现类(); List list new ArrayList(); List实现类特点和性能分析: 三者共同的特点(共同遵循的规范): 1):允许元素重复. 2):记录元素的先后添加顺序. Vector类: 底层才有数组结构算法,方法都使用了synchronized修饰,线程安全,但是性能…

Java集合框架-重构设计

根据Vector类,ArrayList类,LinkedList类所有具有的存储特点以及拥有的方法入手,发现共性就往上抽取. 共同的特点: 1):允许元素重复的. 2):会记录先后添加的顺序. 共同的方法: 如下图. 根据他们的特点,我就可以指定规范: 遵循该规范的实现类,无论底层算法如何,都必须保证允…

Canal Mysql binlog 同步至 Hbase ES

文章目录一、Canal介绍工作原理canal 工作原理二、下载三、安装使用Mysql准备canal 安装解压缩 canal-deployer配置修改启动查看server日志查看instance日志服务停止canal-client使用Canal Adapter数据同步Hbase数据同步ElasticSearch一、Canal介绍 早期阿里巴巴因为杭州和美国…

java中集合的迭代操作

集合的迭代操作: 把集合做的元素一个一个的遍历取出来. 迭代器对象: Iterator: 迭代器对象,只能从上往下迭代. boolean hasNext(); 判断当前指针后是否有下一个元素 Object next():获取指针的下一个元素,并且移动指针. ListIterator: 是Iterator接口的子接口,支持双向迭代…

用C++11的std::async代替线程的创建

转自&#xff1a;http://www.cnblogs.com/qicosmos/p/3534211.html c11中增加了线程&#xff0c;使得我们可以非常方便的创建线程&#xff0c;它的基本用法是这样的&#xff1a; void f(int n); std::thread t(f, n 1); t.join(); 但是线程毕竟是属于比较低层次的东西&#xf…

HashSet类

Set是Collection子接口&#xff0c;模拟了数学上的集的概念。 Set集合存储特点: 1):不允许元素重复. 2):不会记录元素的先后添加顺序. Set只包含从Collection继承的方法&#xff0c;不过Set无法记住添加的顺序&#xff0c;不允许包含重复的元素。当试图添加两个相同元素进Se…

Canal Mysql同步至ES/Hbase只有新增时生效,修改删除不生效

问题描述 新增Mysql数据时&#xff0c;ES、Hbase数据会同步成功&#xff1b;当删除Mysql数据&#xff0c;或者修改Mysql数据时同步ES、Hbase数据无变化(PS:修改和删除加上LIMIT xxx 就可以成功。) 问题分析 通过查看日志发现新增和删除记录的日志区别&#xff1a;新增data有…

LinkedHashSet类

List接口: 允许元素重复,记录先后添加顺序. Set接口: 不允许元素重复,不记录先后添加顺序. 需求: 不允许元素重复,但是需要保证先后添加的顺序. LinkedHashSet:底层才有哈希表和链表算法. 哈希表:来保证唯一性,.此时就是HashSet,在哈希表中元素没有先后顺序. 链表: 来记录…

Canal Mysql binlog 同步至 ElasticSearch 详细介绍

文章目录数据同步ElasticSearch单表基本配置适配器映射文件详细介绍&#xff08;单表、多表映射介绍&#xff09;单表映射索引示例sql单表映射索引示例sql带函数或运算操作多表映射(一对一, 多对一)索引示例sql多表映射(一对多)索引示例sql其它类型的sql示例注意事项本文详细介…

基于C++11的线程池

背景 在传统的收到任务即创建线程的情况下&#xff0c;我们每收到一个任务&#xff0c;就创建一个线程&#xff0c;执行任务&#xff0c;销毁线程&#xff0c; 我们把这三个过程所用的时间分别记做T1,T2,T3 任务本身所用的时间仅占T2/(T1T2T3),这在任务本身所用时间很短的情况下…

集合的工具类

集合操作的工具类: 1):Arrays类: 2):Collections类. Arrays类: 在Collection接口中有一个方法叫toArray把集合转换为Object数组. 把集合转换为数组: Object[] arr 集合对象.toArray(); 数组也可以转换为集合(List集合): public static List asList(T… a) 等价于public …

Docker入门到精通开发指南(一文搞懂)

文章目录安装官方安装文档具体安装步骤1.卸载之前的版本(如果之前未用过忽略该步骤)2.安装相关依赖3.设置docker镜像4.安装docker安装latest版本指定版本安装5.启动docker6.查看docker版本7.运行一个docker hello world8.卸载docker9.配置阿里云镜像加速地址docker常用命令dock…