经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C++ » 查看文章
c/c++ 多线程 利用条件变量实现线程安全的队列
来源:cnblogs  作者:小石王  时间:2018/11/19 9:24:10  对本文有异议

多线程 利用条件变量实现线程安全的队列

背景:标准STL库的队列queue是线程不安全的。

利用条件变量(Condition variable)简单实现一个线程安全的队列。

代码:

  1. #include <queue>
  2. #include <memory>
  3. #include <mutex>
  4. #include <condition_variable>
  5. #include <iostream>
  6. #include <thread>
  7. template<typename T>
  8. class threadsave_queue{
  9. private:
  10. mutable std::mutex mut;//必须是mutable,因为empty是const方法,但是要锁mut,锁操作就是改变操作
  11. std::queue<T> data_queue;
  12. std::condition_variable data_cond;
  13. public:
  14. threadsave_queue(){}
  15. threadsave_queue(threadsave_queue const& other){
  16. std::lock_guard<std::mutex> lk(other.mut);
  17. data_queue = other.data_queue();
  18. }
  19. void push(T new_value){
  20. std::lock_guard<std::mutex> lk(mut);
  21. data_queue.push(new_value);
  22. data_cond.notify_one();
  23. }
  24. void wait_and_pop(T& value){
  25. std::unique_lock<std::mutex> lk(mut);
  26. data_cond.wait(lk, [this]{return !data_queue.empty();});
  27. value = data_queue.front();
  28. data_queue.pop();
  29. }
  30. std::shared_ptr<T> wait_and_pop(){
  31. std::unique_lock<std::mutex> lk(mut);
  32. data_cond.wait(lk, [this]{return !data_queue.empty();});
  33. std::shared_ptr<T> res(std::make_shared<T>(data_queue.front()));
  34. data_queue.pop();
  35. return res;
  36. }
  37. bool empty()const{
  38. std::lock_guard<std::mutex> lk(mut);
  39. return data_queue.empty();
  40. }
  41. };
  42. void make_data(threadsave_queue<int>& tq, int val){
  43. tq.push(val);
  44. }
  45. void get_data1(threadsave_queue<int>& tq, int& d1){
  46. tq.wait_and_pop(d1);
  47. }
  48. void get_data2(threadsave_queue<int>& tq, int& d1){
  49. auto at = tq.wait_and_pop();
  50. d1 = *at;
  51. }
  52. int main(){
  53. threadsave_queue<int> q1;
  54. int d1;
  55. std::thread t1(make_data, std::ref(q1), 10);
  56. std::thread t2(get_data1, std::ref(q1),std::ref(d1));
  57. t1.join();
  58. t2.join();
  59. std::cout << d1 << std::endl;
  60. std::thread t3(make_data, std::ref(q1), 20);
  61. std::thread t4(get_data2, std::ref(q1),std::ref(d1));
  62. t3.join();
  63. t4.join();
  64. std::cout << d1 << std::endl;
  65. q1.empty();
  66. }

github源代码

编译方法:

  1. g++ -g XXX.cpp -std=c++11 -L/home/ys/Downloads/boost_1_68_0/stage/lib -lboost_thread -lboost_system -pthread

编译或者运行有问题的,请参考多线程 boost编译与运行的坑

c/c++ 学习互助QQ群:877684253

本人微信:xiaoshitou5854

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号