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;
}

handy源码阅读(三):SafeQueue类的更多相关文章

  1. 25 BasicUsageEnvironment0基本使用环境基类——Live555源码阅读(三)UsageEnvironment

    25 BasicUsageEnvironment0基本使用环境基类——Live555源码阅读(三)UsageEnvironment 25 BasicUsageEnvironment0基本使用环境基类— ...

  2. 24 UsageEnvironment使用环境抽象基类——Live555源码阅读(三)UsageEnvironment

    24 UsageEnvironment使用环境抽象基类——Live555源码阅读(三)UsageEnvironment 24 UsageEnvironment使用环境抽象基类——Live555源码阅读 ...

  3. 26 BasicUsageEnvironment基本使用环境——Live555源码阅读(三)UsageEnvironment

    26 BasicUsageEnvironment基本使用环境--Live555源码阅读(三)UsageEnvironment 26 BasicUsageEnvironment基本使用环境--Live5 ...

  4. SparkSQL(源码阅读三)

    额,没忍住,想完全了解sparksql,毕竟一直在用嘛,想一次性搞清楚它,所以今天再多看点好了~ 曾几何时,有一个叫做shark的东西,它改了hive的源码...突然有一天,spark Sql突然出现 ...

  5. handy源码阅读(二):EventsImp类

    EventsImp用于完成事件的处理. class EventsImp { EventBase* base_; PollerBase* poller_; std::atomic<bool> ...

  6. handy源码阅读(六):tcp类

    首先是tcpconn和tcpserver类: struct TcpConn : public std::enable_shared_from_this<TcpConn>, private ...

  7. handy源码阅读(六):udp类

    分为UdpServer类和UdpConn类. struct UdpServer : public std::enable_shared_from_this<UdpServer>, priv ...

  8. handy源码阅读(四):Channel类

    通道,封装了可以进行epoll的一个fd. struct Channel: private noncopyable { Channel(EventBase* base, int fd, int eve ...

  9. handy源码阅读(一):EventBase类

    类EventBase继承于类EventBases,继承于noncopyable.  其中noncopyable是一个去除了拷贝构造和赋值构造的类. noncopyable: class noncopy ...

随机推荐

  1. fedora23安装firefox中的flash插件-最终解决问题是: 要给libflashplayer.so以777权限, 开始给的755权限没有实现!

    下载的flash插件是一个rpm包. ===================================== rpm查看文件属于哪个包? 要看这个rpm包安装过还是没有安装过? (如果不用-p就是 ...

  2. EntityFrameworkCore.MySql

    1.点击“工具”->“NuGet包管理器”->“程序包管理器控制台” 分别安装以下几个包 Mysql 版本: Install-Package MySql.Data.EntityFramew ...

  3. linux环境常用分析日志的几个命令

    前言: 分析日志是定位问题的常用手段,但实际线上可能有大量日志,掌握一些常见查看.过滤和分析日志的命令能起到事半功倍的效果.下面列出工作中最常用的一些命令,可在具体使用是查看,尝试使用.实际使用使往往 ...

  4. Jmeter之正则表达式提取器

    在很多情况下,我们需要提取响应结果中的一些信息,供后续功能使用.可以使用后置处理器中的正则表达式提取器. 一.正则表达式提取器 二.配置说明 1.姓名:标识 2.注释:备注 3.Apply to:正则 ...

  5. 16/7/7_PHP-方法重载

    PHP中的重载指的是动态的创建属性与方法,是通过魔术方法来实现的.属性的重载通过__set,__get,__isset,__unset来分别实现对不存在属性的赋值.读取.判断属性是否设置.销毁属性. ...

  6. 应用安全 - 工具使用 - Nmap

    TCP端口扫描类型 TCP connect扫描 三次握手完成/全连接/速度慢/易被检测到 TCP SYN扫描 半开扫描/发送SYN包启动TCP会话 TCP FIN扫描 半开扫描/发送SYN包启动TCP ...

  7. Mac013--Docker安装

    一.Docker安装教程 参考:http://www.runoob.com/docker/macos-docker-install.html 可应用brew命令安装,也可自定义下载安装. 应用brew ...

  8. python批量下载验证码,用来做验证码处理

    刚学到爬虫识别验证码,所以自己建一个获取验证码的类,感兴趣的道友,可以看看,代码如下: import requests import time import os import re class Pi ...

  9. 20191003 尚硅谷Spring Cloud教学视频

    视频信息 视频日期:2018-4-19 讲师:尚硅谷周阳 Spring Cloud版本:Dalston.RELEASE 当前版本:Greenwich SR3 微服务.微服务架构.Spring Clou ...

  10. 20190901 On Java8 第十五章 异常

    第十五章 异常 要想创建健壮的系统,它的每一个构件都必须是健壮的. 异常概念 C++的异常处理机制基于 Ada,Java 中的异常处理则建立在 C++的基础之上(尽管看上去更像 Object Pasc ...