欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-05-29 11:40:18
多线程 利用条件变量实现线程安全的队列 背景:标准STL库的队列queue是线程不安全的。 利用条件变量(Condition variable)简单实现一个线程安全的队列。 代码: c++ include include include include include include templat ......

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

背景:标准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();

}

编译方法:

g++ -g xxx.cpp -std=c++11 -l/home/ys/downloads/boost_1_68_0/stage/lib  -lboost_thread -lboost_system -pthread

编译或者运行有问题的,请参考

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

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

本人微信:xiaoshitou5854