【C++】线程安全的队列

#ifndef THREADSAFE_QUEUE_HPP_
#define THREADSAFE_QUEUE_HPP_

#include <condition_variable>
#include <mutex>
#include <queue>

#define MAX_QUEUE_SIZE 20
template <typename T>
class ThreadSafeQueue {
 public:
  ThreadSafeQueue() = default;
  ThreadSafeQueue(const ThreadSafeQueue& other) = delete;
  ThreadSafeQueue& operator=(const ThreadSafeQueue& other) = delete;

  bool TryPop(T& value);  // NOLINT

  void WaitAndPop(T& value);  // NOLINT

  bool WaitAndTryPop(T& value, const std::chrono::microseconds rel_time);  // NOLINT

  void Push(const T& new_value);  // NOLINT

  void PushWithLimit(const T& new_value);

  bool Empty() {
    std::lock_guard<std::mutex> lk(data_m_);
    return q_.empty();
  }

  void Clear();

  uint32_t Size() {
    std::lock_guard<std::mutex> lk(data_m_);
    return q_.size();
  }

 private:
  std::mutex data_m_;
  std::queue<T> q_;
  std::condition_variable notempty_cond_;
};

template <typename T>
bool ThreadSafeQueue<T>::TryPop(T& value) {  // NOLINT
  std::lock_guard<std::mutex> lk(data_m_);
  if (q_.empty()) {
    return false;
  } else {
    value = q_.front();
    q_.pop();
    notempty_cond_.notify_one();
    return true;
  }
}

template <typename T>
void ThreadSafeQueue<T>::WaitAndPop(T& value) {  // NOLINT
  std::unique_lock<std::mutex> lk(data_m_);
  notempty_cond_.wait(lk, [&] { return !q_.empty(); });
  value = q_.front();
  q_.pop();
  notempty_cond_.notify_one();
}

template <typename T>
bool ThreadSafeQueue<T>::WaitAndTryPop(T& value, const std::chrono::microseconds rel_time) {  // NOLINT
  std::unique_lock<std::mutex> lk(data_m_);
  if (notempty_cond_.wait_for(lk, rel_time, [&] { return !q_.empty(); })) {
    value = q_.front();
    q_.pop();
    notempty_cond_.notify_one();
    return true;
  } else {
    return false;
  }
}

template <typename T>
void ThreadSafeQueue<T>::Push(const T& new_value) {
  std::unique_lock<std::mutex> lk(data_m_);
  q_.push(new_value);
  lk.unlock();
  notempty_cond_.notify_one();
}

template <typename T>
void ThreadSafeQueue<T>::PushWithLimit(const T& new_value) {
  std::unique_lock<std::mutex> lk(data_m_);
  while(q_.size() >= MAX_QUEUE_SIZE) {
    notempty_cond_.wait(lk);
  }
  q_.push(new_value);
  lk.unlock();
  notempty_cond_.notify_one();
}

template <typename T>
void ThreadSafeQueue<T>::Clear() {  // NOLINT
  std::lock_guard<std::mutex> lk(data_m_);
  while (!q_.empty())
    q_.pop();
}


#endif  // THREADSAFE_QUEUE_HPP_

参考自寒武纪cnstream开源项目

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值