handy源码阅读(三):SafeQueue类

SafeQueue类继承与信号量mutex(用于加锁),nonocopyable

定义如下:

template <typename T>
struct SafeQueue : private std::mutex, private noncopyable {
  static const int wait_infinite = std::numeric_limits<int>::max();

  SafeQueue(size_t capacity = 0) : capacity_(capacity), exit_(false) {}
  bool push(T&& v)
  T pop_wait(int waitMs = wait_infinite);
  bool pop_wait(T* v, int waitMs = wait_infinite);

  size_t size();
  void exit();
  bool exited() {  return exit_; }

private:
  std::list<T> items_;
  std::condition_variable ready_;
  size_t capacity_;
  std::atomic<bool> exit_;
  void wait_ready(std::unique_lock<std::mutex>& lk, int waitMs); 
};

该类可以安全的添加和删除任务,类内部使用容器list来存储具体的任务,具有退出状态:exit_,取出任务时可以设定超时时间。

其中Task的定义为:typedef std::function<void()> Task;  Task为返回值为空的函数对象

SafeQueue的具体实现如下:

template <typename T>
size_t SafeQueue<T>::size() {
  std::lock_guard(std::mutex) lk(*this);
  return items_.size();
}

template <typename T>
void SafeQueue<T>::exit() {
  exit_ = true;
  std::lock_guard<std::mutex> lk(*this);
  ready_.notify_all();
}

template <typename T>
bool SafeQueue<T>::push(T&& v) {
  std::lock_guard<std::mutex> lk(*this);
  if (exit_ || (capacity_ && items_.size() >= capacity_)) {
    return false;
  }

  items_.push_back(std::move(v));
  ready_.notify_one();
  return true;
}

template <typename T>
void SafeQueue<T>::wait_ready(std::unique_lock<std::mutex>& lk, int waitMs) {
  if (exit_ || !items_.empty()) {
    return;
  }
  if (waitMs == wait_infinite) {
    ready_.wait(lk, [this] {  return exit_ || !items_.empty();  });
  } else if (waitMs > 0) {
    auto tp = std::chrono::steady_clock::now() + std::chrono::milliseconds(waitMs);
  while (ready_.wait_until(lk, tp) != std::cv_status::timeout && items_.empty() && !exit_) {
  }
  }
}

template <typename T>
bool SafeQueue<T>::pop_wait(T* v, int waitMs) {
  std::unique_lock<std::mutex> lk(*this);
  wait_ready(lk, waitMs);
  if (items_.empty()) {
    return false;
  }

  *v = std::move(items_.front());
  items_.pop_front();
  return true;
}

template <typename T>
T SafeQueue<T>::pop_wait(int waitMs) {
  std::unique_lock<std::mutex> lk(*this);
  wait_ready(lk, waitMs);
  if (items_.empty()) {
    return T();
  }
  T r = std::move(items_.front());
  items_.pop_front();
  return r;
}

 

转载于:https://www.cnblogs.com/sssblog/p/11552037.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值