线程安全的队列

news2024/10/5 13:37:09

学习一下别人写的,线程安全的队列代码。https://github.com/markparticle/WebServer/blob/master/code/log/blockqueue.hicon-default.png?t=N7T8https://github.com/markparticle/WebServer/blob/master/code/log/blockqueue.h

/*
 * @Author       : mark
 * @Date         : 2020-06-16
 * @copyleft Apache 2.0
 */ 
#ifndef BLOCKQUEUE_H
#define BLOCKQUEUE_H

#include <mutex>
#include <deque>
#include <condition_variable>
#include <sys/time.h>

template<class T>
class BlockDeque {
public:
    explicit BlockDeque(size_t MaxCapacity = 1000);

    ~BlockDeque();

    void clear();

    bool empty();

    bool full();

    void Close();

    size_t size();

    size_t capacity();

    T front();

    T back();

    void push_back(const T &item);

    void push_front(const T &item);

    bool pop(T &item);

    bool pop(T &item, int timeout);

    void flush();

private:
    std::deque<T> deq_;

    size_t capacity_;

    std::mutex mtx_;

    bool isClose_;

    std::condition_variable condConsumer_;

    std::condition_variable condProducer_;
};


template<class T>
BlockDeque<T>::BlockDeque(size_t MaxCapacity) :capacity_(MaxCapacity) {
    assert(MaxCapacity > 0);
    isClose_ = false;
}

template<class T>
BlockDeque<T>::~BlockDeque() {
    Close();
};

template<class T>
void BlockDeque<T>::Close() {
    {   
        std::lock_guard<std::mutex> locker(mtx_);
        deq_.clear();
        isClose_ = true;
    }
    condProducer_.notify_all();
    condConsumer_.notify_all();
};

template<class T>
void BlockDeque<T>::flush() {
    condConsumer_.notify_one();
};

template<class T>
void BlockDeque<T>::clear() {
    std::lock_guard<std::mutex> locker(mtx_);
    deq_.clear();
}

template<class T>
T BlockDeque<T>::front() {
    std::lock_guard<std::mutex> locker(mtx_);
    return deq_.front();
}

template<class T>
T BlockDeque<T>::back() {
    std::lock_guard<std::mutex> locker(mtx_);
    return deq_.back();
}

template<class T>
size_t BlockDeque<T>::size() {
    std::lock_guard<std::mutex> locker(mtx_);
    return deq_.size();
}

template<class T>
size_t BlockDeque<T>::capacity() {
    std::lock_guard<std::mutex> locker(mtx_);
    return capacity_;
}

template<class T>
void BlockDeque<T>::push_back(const T &item) {
    std::unique_lock<std::mutex> locker(mtx_);
    while(deq_.size() >= capacity_) {
        condProducer_.wait(locker);
    }
    deq_.push_back(item);
    condConsumer_.notify_one();
}

template<class T>
void BlockDeque<T>::push_front(const T &item) {
    std::unique_lock<std::mutex> locker(mtx_);
    while(deq_.size() >= capacity_) {
        condProducer_.wait(locker);
    }
    deq_.push_front(item);
    condConsumer_.notify_one();
}

template<class T>
bool BlockDeque<T>::empty() {
    std::lock_guard<std::mutex> locker(mtx_);
    return deq_.empty();
}

template<class T>
bool BlockDeque<T>::full(){
    std::lock_guard<std::mutex> locker(mtx_);
    return deq_.size() >= capacity_;
}

template<class T>
bool BlockDeque<T>::pop(T &item) {
    std::unique_lock<std::mutex> locker(mtx_);
    while(deq_.empty()){
        condConsumer_.wait(locker);
        if(isClose_){
            return false;
        }
    }
    item = deq_.front();
    deq_.pop_front();
    condProducer_.notify_one();
    return true;
}

template<class T>
bool BlockDeque<T>::pop(T &item, int timeout) {
    std::unique_lock<std::mutex> locker(mtx_);
    while(deq_.empty()){
        if(condConsumer_.wait_for(locker, std::chrono::seconds(timeout)) 
                == std::cv_status::timeout){
            return false;
        }
        if(isClose_){
            return false;
        }
    }
    item = deq_.front();
    deq_.pop_front();
    condProducer_.notify_one();
    return true;
}

#endif // BLOCKQUEUE_H

1,原理

利用c++  std::deque 队列,存储数据。

使用两个std::condition_variable 实现生产者和消费者。

使用std::mutex 锁,控制生产者和消费者对队列的控制权。

2, 构造函数

给isClose赋值为false,初始化队列的长度,也可以使用默认值。

3,析构函数

清空队列,设置isClose=false,并唤醒生产者和消费者。

唤醒后,如果此时 消费者或者生产者正在阻塞,则会继续进行,并且检测到了isClose_=false,则会正常退出。再使用信号量 wait 时,析构时要让阻塞去掉,然后函数正常返回。

4,加入元素

 分为从前边加,和从后边加,逻辑时一样的。首先对 队列加锁,然后判断当前队列的长度是否大于设定的容量,如果超出则生产者信号量需要阻塞等待,直到消费者 消费了一个,然后继续向下执行添加逻辑。如果不大于设定的长度,则正常向队列添加一个元素,然后唤醒消费者 信号量,取消费。

5,取出元素

 先给队列加锁保护,然后判断队列是否为空。如果为空,则说明队列没有元素,消费者等待。如果不为空,则正常取出,然后通知生产者继续生产。

这里还有一个函数,用来超时判断,如果队列为空,则等待一定秒数,如果这个时间过后,仍然为空,则直接返回false.

6,其它

clear()  清空队列

empty() 判断队列是否为空

full() 判断是否已满

front() 返回第一个,不会取出

back() 返回最后一个,不会取出

7,测试一下

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1480230.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【嵌入式——QT】QListWidget

QListWidget类提供了一个基于项的列表小部件&#xff0c;QListWidgetItem是列表中的项&#xff0c;该篇文章中涉及到的功能有添加列表项&#xff0c;插入列表项&#xff0c;删除列表项&#xff0c;清空列表&#xff0c;向上移动列表项&#xff0c;向下移动列表项。 常用API a…

MySQL-CDC 新增同步表确无法捕获增量问题处理

Flink-CDC版本&#xff1a;2.3.0 问题描述 之前通过Flink-CDC捕获Mysql数据库的数据变更情况&#xff0c;代码大致如下&#xff1a; StreamExecutionEnvironment env StreamExecutionEnvironment.getExecutionEnvironment(flinkEnvConf);MySqlSource<String> mysql …

智能咖啡厅助手:人形机器人 +融合大模型,行为驱动的智能咖啡厅机器人(机器人大模型与具身智能挑战赛)

智能咖啡厅助手&#xff1a;人形机器人 融合大模型&#xff0c;行为驱动的智能咖啡厅机器人(机器人大模型与具身智能挑战赛) “机器人大模型与具身智能挑战赛”的参赛作品。的目标是结合前沿的大模型技术和具身智能技术&#xff0c;开发能在模拟的咖啡厅场景中承担服务员角色并…

adb下载安装及使用教程

adb下载安装及使用教程 一、ADB的介绍1.ADB是什么&#xff1f;2.内容简介3.ADB常用命令1. ADB查看设备2. ADB安装软件3. ADB卸载软件4. ADB登录设备shell5. ADB从电脑上发送文件到设备6. ADB从设备上下载文件到电脑7. ADB显示帮助信息 4.为什么要用ADB 二、ADB的下载1.Windows版…

「MySQL」增删查改

在操作数据库中的表时&#xff0c;需要先使用该数据库&#xff1a; use database;新增 创建表 先用 use 指定一个数据库,然后使用 create 新增一个表 比如建立一个学生表 mysql> use goods; mysql> create table student(-> name varchar(4),-> age int,-> …

Linux系统---nginx(4)负载均衡

目录 1、服务器配置指令 ​编辑 1.1 服务器指令表 1.2 服务器指令参数 2、负载均衡策略指令 2.1 轮询 &#xff08;1) 加权轮询 &#xff08;2) 平滑轮询 2.2 URL 哈希&#xff08;一致性哈希&#xff09; 2.3 IP哈希策略 2.4 最少连接 Nginx 负载均衡是由代理模块和上…

爱心商城|爱心商城系统|基于Springboot的爱心商城系统设计与实现(源码+数据库+文档)

爱心商城系统目录 目录 基于Springboot的爱心商城系统设计与实现 一、前言 二、系统功能设计 三、系统功能设计 1、商品管理 2、捐赠管理 3、公告管理 4、公告类型管理 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#x…

ssm274办公自动化管理系统

** &#x1f345;点赞收藏关注 → 私信领取本源代码、数据库&#x1f345; 本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目希望你能有所收获&#xff0c;少走一些弯路。&#x1f345;关注我不迷路&#x1f345;** 一 、设计说明 1.1课题背…

图结构数据的构建-DGL库

官方文档 一、图的特点 同构性与异构性 相比同构图&#xff0c;异构图里可以有不同类型的节点和边。这些不同类型的节点和边具有独立的ID空间和特征&#xff1b;同构图和二分图只是一种特殊的异构图&#xff0c;它们只包括一种关系 节点与边 有向图一条边、无向图两条边、…

天津廉租房如何申请取得廉租住房租房补贴资格

如何申请廉租住房租赁补贴资格&#xff1f; 低收入住房困难家庭应当向户籍所在地街道办事处&#xff08;乡镇人民政府&#xff09;提出申请。 申请时&#xff0c;您需要提供以下要求的原件和复印件&#xff1a; &#xff08;一&#xff09;您及家人的身份证件&#xff1b; &a…

React富文本编辑器开发(二)

我们接着上一节的示例内容&#xff0c;现在有如下需求&#xff0c;我们希望当我们按下某个按键时编辑器有所反应。这就需要我们对编辑器添加事件功能onKeyDown, 我们给 Editor添加事件&#xff1a; SDocor.jsx import { useState } from react; import { createEditor } from…

羊大师分享,羊奶奶有哪些对健康有益的喝法?

羊大师分享&#xff0c;羊奶奶有哪些对健康有益的喝法&#xff1f; 羊奶奶有多种对健康有益的喝法&#xff0c;以下是一些建议&#xff1a; 直接饮用&#xff1a;将羊奶直接煮沸后饮用&#xff0c;可以保留羊奶中的营养成分&#xff0c;为身体提供全面的滋养。羊奶的丰富蛋白质…

从李一舟看AI浪潮: 聚合数据教你如何把握数据的真正价值

AI热潮的追捧与质疑 在人工智能&#xff08;AI&#xff09;技术的浪潮中&#xff0c;每天都有新的进展让我们惊叹不已。最近&#xff0c;OpenAI的Sora模型如同一颗璀璨的明星&#xff0c;闪耀在科技界的夜空。与此同时&#xff0c;各种AI相关的产品和课程如同春雨后的竹笋&…

四川易点慧电子商务有限公司抖音小店靠谱吗?

在当下电商行业风起云涌的时代&#xff0c;四川易点慧电子商务有限公司作为抖音小店的一家新兴力量&#xff0c;是否靠谱成为了许多消费者和创业者关注的焦点。今天&#xff0c;我们就来深度解析一下这家公司&#xff0c;看看它的抖音小店究竟靠不靠谱。 一、公司背景介绍 四川…

【Mars3d】进行水平测量measure.area({的时候,会被模型遮挡的处理方法

问题&#xff1a; 1.thing/analysis/measure 水平面积 measure.area({ 在模型上测量的时候会被遮挡 2. 通过 addHeight:10000,增加高度也不可以实现这种被遮挡的效果&#xff0c;都增加到10000了&#xff0c;还是会被遮挡 export function measureArea() { measure.area({ s…

释放 群星聚落 时 自动魔免【War3地图编辑器】

文章目录 前言实现原理具体步骤1、创建隐形单位2、新建触发器2.1、新事件开端 2.2、环境→新条件2.3、动作2.3.1、创建单位2.3.2、单位 发布指令(指定单位) 前言 白虎 在斗蛐蛐中又称 白给&#xff0c;因为战绩长期倒数单挑能力和大法师并列倒数第一然而在实战中&#xff0c;大…

【Linux C | 网络编程】getaddrinfo 函数详解及C语言例子

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

视频和音频使用ffmpeg进行合并和分离(MP4)

1.下载ffmpeg 官网地址&#xff1a;https://ffmpeg.org/download.html 2.配置环境变量 此电脑右键点击 属性 - 高级系统配置 -高级 -环境变量 - 系统变量 path 新增 文件的bin路径 3.验证配置成功 ffmpeg -version 返回版本信息说明配置成功4.执行合并 ffmpeg -i 武家坡20…

群控代理IP搭建教程:打造一流的网络爬虫

目录 前言 一、什么是群控代理IP&#xff1f; 二、搭建群控代理IP的步骤 1. 获取代理IP资源 2. 配置代理IP池 3. 选择代理IP策略 4. 编写代理IP设置代码 5. 异常处理 三、总结 前言 群控代理IP是一种常用于网络爬虫的技术&#xff0c;通过使用多个代理IP实现并发请求…

【设计模式】(二、)设计模式六大设计原则

一、 设计原则概述 设计模式中主要有六大设计原则&#xff0c;简称为SOLID &#xff0c;是由于各个原则的首字母简称合并的来(两个L算一个,solid 稳定的)&#xff0c;六大设计原则分别如下&#xff1a; ​ 1、单一职责原则&#xff08;Single Responsibitity Principle&#…