博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++ boost thread学习(二)
阅读量:6067 次
发布时间:2019-06-20

本文共 2765 字,大约阅读时间需要 9 分钟。

 

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

你可能感兴趣的文章
什么是linux的ftp
查看>>
Python命令行解析argparse常用语法使用简介
查看>>
Spring 4 官方文档学习(十二)View技术
查看>>
jsp页面验证码(完整实例)
查看>>
学习建模 - UML
查看>>
Android解析WindowManager(一)WindowManager体系
查看>>
一个想法(续二):换个角度思考如何解决IT企业招聘难的问题!
查看>>
tomcat指定配置文件路径方法
查看>>
一些常见的关于Linux系统的问题
查看>>
推荐一款jQuery ColorPicked 颜色拾取器插件
查看>>
javaweb学习总结(二十三)——jsp自定义标签开发入门
查看>>
网络编程中的CAP & 有趣的存储框架(关系型、NoSQL)全图
查看>>
[Linux内核]ctrl-z/fg/bg/nohup/setsid/()与&/disown/screen
查看>>
VS没办法调试,直接退出,报错:1. 使用调试生成配置或禁用调试选项“启用‘仅我的代码’”。。。...
查看>>
C# 委托应用总结
查看>>
Linux驱动技术(七) _内核定时器与延迟工作
查看>>
裁判文书网采集说明
查看>>
Reverse Engineering Custom DataTypes -> GUID() in SQL Server to PostgreSQL
查看>>
配置Tomcat apr运行模式
查看>>
BZOJ3490 : Pa2011 Laser Pool
查看>>