条件变量

如果线程之间执行顺序上有依赖关系,可使用条件变量(Condition variables)。

可以到boost官网中参考条件变量(Condition variables)的使用。

条件变量必须和互斥量配合使用,等待另一个线程重某个事件的发生(满足某个条件),然后线程才能继续执行。

共有两种条件变量对象condition_variable, condition_variable_any,一般情况下使用condition_variable_any。

条件变量的使用方式: 
拥有条件变量的线程先锁定互斥量,然后循环检查某个条件,如果条件不满足,那么就调用条件变量的成员函数wait()等待直到条件满足。其他线程处理条件变量要求的条件,当条件满足时调用它的成员函数notify_one()或者notify_all(),以通知一个或者所有正在等待条件的变量的线程停止等待继续执行。

例子:生产--消费模型。

缓冲区buffer使用了两个条件变量cond_put和cond_get,分别用于处理put动作和get动作,如果缓冲区满则cond_put持续等待,当cond_put得到通知 (缓冲区不满)时线程写入数据,然后通知cond_get条件变量可以获取数据。cond_get的处理流程与cond_put类似。

C++代码  
  1. #include <boost/thread.hpp>
  2. #include <boost/thread/mutex.hpp>
  3. #include <iostream>
  4. #include <stack>
  5. using namespace std;
  6. boost::mutex io_mu;
  7. class buffer
  8. {
  9. private:
  10. boost::mutex mu; // 互斥量,配合条件变量使用
  11. boost::condition_variable_any cond_put; // 写入条件变量
  12. boost::condition_variable_any cond_get; // 读取条件变量
  13. stack<int> stk; // 缓冲区对象
  14. int un_read, capacity;
  15. bool is_full() // 缓冲区满判断
  16. {
  17. return un_read == capacity;
  18. }
  19. bool is_empty()  // 缓冲区空判断
  20. {
  21. return un_read == 0;
  22. }
  23. public:
  24. buffer(size_t n) : un_read(0), capacity(n){}  // 构造函数
  25. void put(int x)  // 写入数据
  26. {
  27. { // 开始一个局部域
  28. boost::mutex::scoped_lock lock(mu); //锁定互斥量
  29. while ( is_full() ) // 检查缓冲区是否满
  30. {
  31. { // 局部域,锁定cout输出一条信息
  32. boost::mutex::scoped_lock lock(io_mu);
  33. cout << "full waiting..." << endl;
  34. }
  35. cond_put.wait(mu); // 条件变量等待
  36. } // 条件变脸满足,停止等待
  37. stk.push(x); // 压栈,写入数据
  38. ++un_read;
  39. } // 解锁互斥量,条件变量的通知不需要互斥量锁定
  40. cond_get.notify_one(); // 通知可以读取数据
  41. }
  42. void get(int *x) // 读取数据
  43. {
  44. { // 局部域开始
  45. boost::mutex::scoped_lock lock(mu); // 锁定互斥量
  46. while (is_empty()) // 检查缓冲区是否空
  47. {
  48. {
  49. boost::mutex::scoped_lock lock(io_mu);
  50. cout << "empty waiting..." << endl;
  51. }
  52. cond_get.wait(mu); // 条件变量等待
  53. }
  54. --un_read;
  55. *x = stk.top(); // 读取数据
  56. stk.pop(); // 弹栈
  57. }
  58. cond_put.notify_one(); // 通知可以写入数据
  59. }
  60. };
  61. buffer buf(5); // 一个缓冲区对象
  62. void producter(int n) // 生产者
  63. {
  64. for (int i = 0; i < n; ++i)
  65. {
  66. {
  67. boost::mutex::scoped_lock lock(io_mu);
  68. cout << "put " << i << endl;
  69. }
  70. buf.put(i); // 写入数据
  71. }
  72. }
  73. void consumer(int n) // 消费者
  74. {
  75. int x;
  76. for (int i = 0; i < n; ++i)
  77. {
  78. buf.get(&x); // 读取数据
  79. boost::mutex::scoped_lock lock(io_mu);
  80. cout << "get " << x << endl;
  81. }
  82. }
  83. int main()
  84. {
  85. boost::thread t1(producter, 20); // 一个生产者线程
  86. boost::thread t2(consumer, 10); // 两个消费者线程
  87. boost::thread t3(consumer, 10);
  88. t1.join();
  89. t2.join();
  90. t3.join();
  91. return 0;
  92. }

运行结果: 
empty waiting... 
put 0 
empty waiting... 
put 1 
put 2 
get 1 
get 2 
get 0 
empty waiting... 
empty waiting... 
put 3 
put 4 
put 5 
put 6 
put 7 
get 6 
get 7 
get 5 
get 4 
get 3 
empty waiting... 
put 8 
empty waiting... 
put 9 
put 10 
put 11 
get 9 
get 11 
get 8 
empty waiting... 
put 12 
put 13 
put 14 
put 15 
put 16 
put 17 
full waiting... 
get 10 
get 16 
put 18 
full waiting... 
get 17 
get 15 
get 14 
get 13 
get 12 
get 18 
empty waiting... 
put 19 
get 19

转载于:https://www.cnblogs.com/fire909090/p/6801543.html

C++ boost thread学习(二)相关推荐

  1. BOOST THREAD

    转载:http://www.blogjava.net/LittleDS/category/31585.html Boost Thread学习笔记 thread自然是boost ::thread库的主 ...

  2. Boost库学习笔记(二)算法模块-C++11标准

    Boost库学习笔记(二)算法模块-C++11标准 一.综述 Boost.Algorithm是一系列人通用推荐算法的集合,虽然有用的通用算法很多,但是为了保证质量和体积,并不会将太多通用算法通过审查测 ...

  3. C#多线程学习(二) 如何操纵一个线程

    C#多线程学习(二) 如何操纵一个线程 原文链接:http://kb.cnblogs.com/page/42529/ [1] C#多线程学习(二) 如何操纵一个线程 [2] C#多线程学习(二) 如何 ...

  4. boost使用学习总结

    boost常用库案例 http://www.cnblogs.com/wangkangluo1/archive/2011/07/19/2110746.html 1.boost::any boost::a ...

  5. c++ boost多线程学习(一)

    本次学习相关资料如下: Boost C++ 库 第 6 章 多线程(大部分代码的来源) Boost程序库完全开发指南 - 深入C++"准"标准库 第三版 罗剑锋著 头文件: #in ...

  6. hadoop hive hbase 入门学习 (二)

    hadoop 自学系列                hadoop hive hbase 入门学习 (一) hadoop安装.hdfs学习及mapreduce学习 hadoop 软件下载 (hadoo ...

  7. Boost 第十二章 并发编程

    本文章所有内容源于<BOOST程序库完全开发指南:深入C++"准"标准库(第3版)>第十二章 本章内容包括Boost库中的三个并发编程组件.atomic,它实现了C++ ...

  8. boost thread使用方法

    一.创建一个线程 创建线程 boost::thread myThread(threadFun); 需要注意的是:参数可以是函数对象或者函数指针.并且这个函数无参数,并返回void类型. 当一个thre ...

  9. boost::thread模块实现生产者消费者的测试程序

    boost::thread模块实现生产者消费者的测试程序 实现功能 C++实现代码 实现功能 boost::thread模块实现生产者消费者的测试程序 C++实现代码 #include <boo ...

最新文章

  1. java filter 失效_为何java中的过滤器filter不起作用
  2. Oracle数据加载之sqlldr工具的介绍
  3. Vue.js的复用组件开发流程
  4. 2022 年营销自动化七大趋势前瞻
  5. WINFORM 多条件动态查询 通用代码的设计与实现
  6. B2B行业网站电话销售应具备的精神
  7. 斐波那契数列-爬楼梯算法
  8. php 过滤绕过注入,PHPB2B注入#1(绕过过滤)
  9. 漂亮特殊字体可复制 特殊字体生成器
  10. 前端工程师考核总结_web前端年度工作总结
  11. 亚马逊qa是什么意思_“亚马逊成就”是什么意思?
  12. 如何开通企业付款到零钱||小程序红包功能
  13. Android加固调研
  14. 鼠标dpi设置多少合适呢?查看鼠标dpi的方法
  15. 【C++】setw()函数
  16. 技术周刊(第10期):新技术又来了?
  17. 什么是Hadoop - HDFS - MapReduce - YARN - HA
  18. 查看、修改oracle字符集,查看oracle版本
  19. 写python博客的第九天正则的简单简单练习
  20. 情人节福利,恋爱话术微信小程序它来了(开源,看了就懂~,2万字真香警告)

热门文章

  1. chkdsk 检查卷位图时发现损坏_活塞连杆组的分解与组装、活塞环的检查
  2. 如何给图片赋值_医学数据的变量类型及在SPSS中的赋值方法(医学统计前的重要步骤)——【杏花开医学统计】...
  3. 关于流水帐表序列号生成时的并发操作问题
  4. 配置Nginx实现负载均衡
  5. java int转String全部方式的效率对照与深入解析
  6. Nginx如何反向代理网站和设置虚拟主机
  7. 「追根溯源」Ruby数组的uniq方法
  8. BREW中的安全性网络编程
  9. BZOJ1084 SCOI2005最大子矩阵
  10. 最终成为了热门的语言——python