zoukankan      html  css  js  c++  java
  • c/c++ 多线程 利用条件变量实现线程安全的队列

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

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

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

    代码:

    #include <queue>
    #include <memory>
    #include <mutex>
    #include <condition_variable>
    #include <iostream>
    #include <thread>
    
    template<typename T>
    class threadsave_queue{
    private:
      mutable std::mutex mut;//必须是mutable,因为empty是const方法,但是要锁mut,锁操作就是改变操作
      std::queue<T> data_queue;
      std::condition_variable data_cond;
    public:
      threadsave_queue(){}
      threadsave_queue(threadsave_queue const& other){
        std::lock_guard<std::mutex> lk(other.mut);
        data_queue = other.data_queue();
      }
      void push(T new_value){
        std::lock_guard<std::mutex> lk(mut);
        data_queue.push(new_value);
        data_cond.notify_one();
      }
      void wait_and_pop(T& value){
        std::unique_lock<std::mutex> lk(mut);
        data_cond.wait(lk, [this]{return !data_queue.empty();});
        value = data_queue.front();
        data_queue.pop();
      }
    
      std::shared_ptr<T> wait_and_pop(){
        std::unique_lock<std::mutex> lk(mut);
        data_cond.wait(lk, [this]{return !data_queue.empty();});
        std::shared_ptr<T> res(std::make_shared<T>(data_queue.front()));
        data_queue.pop();
        return res;
      }
      
      bool empty()const{
        std::lock_guard<std::mutex> lk(mut);
        return data_queue.empty();
      }
    };
    
    void make_data(threadsave_queue<int>& tq, int val){
      tq.push(val);
    }
    void get_data1(threadsave_queue<int>& tq, int& d1){
      tq.wait_and_pop(d1);
    }
    void get_data2(threadsave_queue<int>& tq, int& d1){
      auto at = tq.wait_and_pop();
      d1 = *at;
    }
    int main(){
      threadsave_queue<int> q1;
      int d1;
      std::thread t1(make_data, std::ref(q1), 10);
      std::thread t2(get_data1, std::ref(q1),std::ref(d1));
      t1.join();
      t2.join();
      std::cout << d1 << std::endl;
      std::thread t3(make_data, std::ref(q1), 20);
      std::thread t4(get_data2, std::ref(q1),std::ref(d1));
      t3.join();
      t4.join();
      std::cout << d1 << std::endl;
      q1.empty();
    
    }
    
    

    github源代码

    编译方法:

    g++ -g XXX.cpp -std=c++11  -pthread
    

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

    本人微信:xiaoshitou5854

  • 相关阅读:
    python gevent(协程模块)
    python基础之socket与socketserver
    python 使用 with open() as 读写文件
    Python logger模块
    python二维码操作:QRCode和MyQR入门
    常见的端口号及其用途
    python中hasattr()、getattr()、setattr()函数的使用
    mysql数据库自带数据库介绍
    关于BeautifulSoup4 解析器的说明
    学习opencv(1)
  • 原文地址:https://www.cnblogs.com/xiaoshiwang/p/9981249.html
Copyright © 2011-2022 走看看