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. ios 无法安装xxx,请稍后再试

    通过xcode可以用模拟机器运行工程,但是 打出包后: 真机安装提示 无法安装xxx,请稍后再试 已经信任了证书 问题原因:xcode配置的 运行手机上的操作系统太高了是 解决办法:deploymen ...

  2. 使用spring提供的@Scheduled注解创建定时任务

    使用方法 操作非常简单,只要按如下几个步骤配置即可 1. 导入jar包或添加依赖,其实定时任务只需要spring-context即可,当然起服务还需要spring-web: 2. 编写定时任务类和方法 ...

  3. Eclipse查看jdk源码(Ctrl+左键)

    Window ->Preferences ->Java ->Installed JREs ->选中jdk ->Edit ->选中rt.jar ->source ...

  4. Codeforces 1042C (贪心+模拟)

    题面 传送门 分析 思路简单,但代码较复杂的贪心 分类讨论: 有0 负数有奇数个:将绝对值最小(实际最大)的负数和0全部乘到一起,最后删掉0 负数有偶数个:将0全部乘到一起,最后删掉0 没有0 负数有 ...

  5. Acwing143. 最大异或对

    在给定的N个整数A1,A2……ANA1,A2……AN中选出两个进行xor(异或)运算,得到的结果最大是多少? 输入格式 第一行输入一个整数N. 第二行输入N个整数A1A1-ANAN. 输出格式 输出一 ...

  6. uve (mui/light7)写APP的使用心得(大坑);

    话说mui这个框架的UI确实挺好看的(个人觉得)所以项目使用了他,结果里面的坑太TM多,不得不说MUI做东西太不用心了,社区不活跃,提问都没人管!; mui第一个坑: 日期选择器默认值无效:使用代码跟 ...

  7. [ZJOI2009]取石子游戏

    瞪了题解两三天,直接下转第二篇题解就康懂了 首先我们令 : \(L[i][j]\) 表示当前 \([i,j]\) 区间左侧放置 \(L[i,j]\) 数量的石子后先手必败 \(R[i][j]\) 表示 ...

  8. ElasticSearch 7.x 默认不在支持指定索引类型

    原文:ElasticSearch 7.x 默认不在支持指定索引类型 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://bl ...

  9. win32 socket 编程(三)——TCP/IP

    一.TCP/IP解析 TCP/IP协议的核心部分是传输层协议(TCP.UDP),网络层协议(IP)和物理接口层,这三层通常是在操作系统内核中实现.因此用户一般不涉及.编程时,编程界面有两种形式: 1. ...

  10. OGG-00303

    解决方案:因为Defgen版本不同,注释数据定义文件对应的行 *Database type:ORACLE,用*在行首注释即可