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 = ) : 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 > ) {
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;
}

最新文章

  1. windows 环境下的redis安装
  2. 升级Win2010后, 打开SQL2008 附加数据库提示 5120错误
  3. [Android Rro] SDK JAR
  4. 安装SQL Server 2005
  5. java中字符串的非空判断
  6. ASP.NET MVC 学习8、Controller中的Detail和Delete方法
  7. 【待填坑】bzoj上WC的题解
  8. 简单方法打包.net程序集脱离framework
  9. groovy学习(一)列表
  10. Jquery(一) 初识Jquery,简单使用Jquery。
  11. EF Core利用Transaction对数据进行回滚保护
  12. Netty(RPC高性能之道)原理剖析
  13. 修复./mysql/proc
  14. 【BZOJ】2331: [SCOI2011]地板
  15. SQL注入之Sqli-labs系列第十二关
  16. 从简单的mongodb example 的观察
  17. HTTP中的Get与Post
  18. httpclient 多线程请求
  19. js--语音播报
  20. Python函数标注

热门文章

  1. mysql语句练习50题
  2. python json字符串中有int类型数字(不带引号)
  3. 如何实现免登陆功能(cookie session?)
  4. 多线程threading初识二--多线程等待
  5. JSONPath解析json
  6. centos6.5搭建禅道
  7. python实现建立websocket通信
  8. rac节点挂掉后,vip飘到别的节点,但是业务连接不上报 no listener问题处理
  9. [Git] 008 status 与 commit 命令的补充
  10. [Web 前端] 002 html 常用行行级元素