c++实现的阻塞队列

2023-05-16

阻塞队列(block_queue)

什么是阻塞队列:

  • 在多线程编程时当有多个线程访问一个队列时如果队列为空,则获取队列中元素的方法就会阻塞,直到队列中有元素可以获取

解决的问题:

  • 队列的线程安全问题
  • 队列多线程取元素时的轮询判断问题

什么情况下需要阻塞队列:

  • 在c++标准库STL中常用的队列容器都不是线程安全的,我们在多线程编程时总会有类似于生产者消费者这种模型,在这种模型下我们访问队列就需要手动加锁,如果队列不是阻塞式的,我们每次从队列中获取元素的时候都需要对队列进行判断,如果队列为空,就continue,这种做法一般都需要配合一个定时器来实现,定时器的时长很难去设定,如果时间过短会一直去轮询,如果时间过长又会导致队列中消息有积压。下面我们通过一段代码来说明。
#include <thread>
#include <vector>
#include <Windows.h>
#include <iostream>
#include <queue>

std::queue<int> testQueue;
std::mutex mtx;

void Producer()
{
	for (size_t i = 0; i < 100; ++i)
	{
		Sleep(100);
		//push之前先进行加锁
		mtx.lock();
		testQueue.push(i);
		mtx.unlock();
	}
}

void Customer(size_t id)
{
	while (1)
	{
		mtx.lock();
		//需要每次都进行判断,如果队列为空就continue,每次队列的读写都得加锁
		if (testQueue.size() == 0)
		{
			Sleep(1);
			mtx.unlock();
			continue;
		}
		auto value = testQueue.front();
		testQueue.pop();
		mtx.unlock();
		std::cout << "thread id: " << id << " value:" << value << std::endl;
	}	
}

int main()
{
	std::vector<std::thread> vTh;
	for (size_t i = 0; i < 10; ++i)
	{
		std::thread t = std::thread(Customer,i);
		vTh.push_back(std::move(t));
	}

	Producer();
	for (auto& it : vTh)
	{
		std::cout << it.get_id() << std::endl;
		if (it.joinable())
		{
			it.join();
		}
	}
	return 0;
}

阻塞队列的实现:

BlockQueue.h

#include<mutex>
#include<list>
#include<condition_variable>
using namespace std;

template <typename T>
class BlockQueue
{
public:
	BlockQueue(){}

	~BlockQueue(){}

	void Put(const T& x)
	{
		unique_lock<mutex> guard(m_mutex);
		m_queue.push_back(x);
		m_cond.notify_all();
	}

	void Put(T&&x)
	{
		unique_lock<mutex> guard(m_mutex);
		m_queue.push_back(move(x));
		m_cond.notify_all();
	}

	T Take()
	{
		unique_lock<mutex> guard(m_mutex);
		while (m_queue.size() == 0)
			m_cond.wait(guard);
		T front(move(m_queue.front()));
		m_queue.pop_front();
		return move(front);
	}

	size_t Size()
	{
		unique_lock<mutex> guard(m_mutex);
		return m_queue.size();
	}

private:
	mutable mutex m_mutex;
	condition_variable m_cond;
	list<T>     m_queue;
};

main.cpp

#include "BlockQueue.h"
#include <thread>
#include <vector>
#include <Windows.h>
#include <iostream>

BlockQueue<int> testQueue;
std::mutex mtx;

void Produce()
{
	for (size_t i = 0; i < 100; ++i)
	{
		Sleep(100);
		testQueue.Put(i);
	}
}

void Custorm(size_t id)
{
	while (1)
	{
		auto value = testQueue.Take();
		std::cout << "thread id: " << id << " value:" << value << std::endl;
	}	
}

int main()
{
	std::vector<std::thread> vTh;
	for (size_t i = 0; i < 10; ++i)
	{
		std::thread t = std::thread(Custorm,i);
		vTh.push_back(std::move(t));
	}

	Produce();
	for (auto& it : vTh)
	{
		std::cout << it.get_id() << std::endl;
		if (it.joinable())
		{
			it.join();
		}
	}
	return 0;
}

说明:

  • 通过对比上面得消费者和生产者模型,我们可以发现,生产者和消费者在使用的时候不需要关心队列的线程安全问题,其次消费者也省去了每次进行判断轮询的操作。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c++实现的阻塞队列 的相关文章

  • 修改svn默认端口

    Subversion有两种不同的配置方式 xff0c 一种基于它自带的轻量级服务器svnserve xff0c 一种基于非常流行的Web服务器Apache 根据不同的配置方式 xff0c Subversion使用不同的端口对外提供服务 基于
  • 项目、系统开发中的需求分析说明书和需求规格说明书的区别

    项目组成员在针对要开发的系统做需求调研后 xff0c 就要编写对应的需求说明书 作为软件工程师 xff0c 你就得知道需求分析说明书和需求规格说明书的区别 xff0c 以期在正确的时候编写正确的需求文档 两者有何不同 xff1a xff08
  • C/C++内存管理详解[转载]

    我觉得这是一篇很不错的文章 xff0c 对C和C 43 43 的程序员来说 xff0c 很有实用价值 xff0c 故推荐给大家 作者 xff1a PingPong 文档来源 xff1a CSDN 伟大的Bill Gates 曾经失言 xff
  • 项目启动会应该注意的几点

    摘要 xff1a 开个好头 xff0c 万事不难 项目启动会作为项目建设生命周期的开始 xff0c 其意义和难度不言而喻 作为项目管理办公室的负责人 xff0c 需要特别重视项目启动会的召开 xff0c 杜绝走过场 xff0c 避免虽然知道
  • 飞机的航班代码/航班号码的编号规则

    以下内容来源于网络 xff0c 并整理而得 一 国内航班 中国国内航班号的编号规则 xff1a 航空公司的两字代码 43 4位数字 其中 xff0c 后面四位数字的第一位代表航空公司的基地所在地区 第二位代表航班基地外终点所在地区 xff0
  • 机场生产运行数据统计指标-第四篇-机场运行保障类

    机场运行保障类 1 民航航班正常统计 1 1 统计说明 xff08 1 xff09 统计范围的相关说明 xff1a 1 民航航班正常统计范围 xff1a 国内外运输航空公司执行的客货运航班 xff0c 包括正班 加班 包机 港澳台地区及国际
  • Python入门学习--环境配置

    工作将近两年了 xff0c 做过B S结构的项目 xff0c 也做过android xff0c 也做过C S结构的项目 xff0c 相信无论是那种项目都是基于Java 学习运用Java也已经好多年了 xff0c 虽然也接触过C C 43 4
  • Python入门学习-数据类型

    一 类型的概念 首先 xff0c 对于一个数据1011100 xff0c 改怎么解释呢 xff1f 同Java等变成语言类型 xff0c 首先我们要明确数据的类型 xff0c 程序设计语言不允许语法歧义 xff0c 因此需要明确数据的类型
  • 流年似水 启航2019

    凌晨1点无意间看到一个演讲视频 感谢你给我机会上场 xff0c 很久之前的一个演讲视频 xff0c 看完除了羡慕还是羡慕吧 xff0c 也许就是一句话吧 xff0c 开挂的人生不需要解释 30多年的生活他做了很多事 xff0c 也做成了很多
  • 使用Python代码下载网易音乐歌曲

    刚刚写了一堆 xff0c 最终放弃了 xff0c 后来百度查找到一个接口 xff0c http music 163 com song media outer url id 61 这里填歌曲id mp3 这个URL就可以下载了 xff0c 现
  • Spring是如何管理Bean

    常常听老师说容器 xff0c 容器是什么 xff1f spring中是如何体现的 xff1f 一直有疑惑 xff0c 这两天看了一下Spring管理bean的Demo xff0c 对于Spring中的容器有了简单的认识 我们知道 xff0c
  • Python如何用TKinter搭建图形界面窗口,并通过多进程的方式调用功能函数

    用Python开发图形界面和程序时 xff0c 经常会对图形界面的搭建感到失望 xff0c 或许是由于对图形界面不熟悉的原因吧 xff0c 总之一想到图形界面 xff0c 就感觉会很费时 费力 xff0c 编程的积极性大幅下降 最近 xff
  • 巧用 Matplotlib 动画,让你的 Python 可视化大放异彩

    柠檬2069 点击右侧关注 xff0c 遇见更好的自己 xff01 巧用 Matplotlib 动画 让你的 Pyt
  • ubuntu里设置从串口登录

    1 Create a file called etc init ttyS0 conf containing the following ttyS0 getty This service maintains a getty on ttyS0
  • Linux proc目录详解

    目录 1 什么是proc 2 proc目录介绍 2 1 proc cpuinifo CPU的信息 型号 家族 缓存大小等 2 2 proc meminfo物理内存 交换空间 2 3 proc mounts 已加载的文件系统的列表 2 4 p
  • Linux 系统守护进程管理 --(start-stop-daemon)

    目录 一 功能 二 格式 2 1 搜索匹配的过程 2 2选项 2 2 1匹配选项 2 2 2只对 start有效的选项 2 2 3只对 停止有效的选项 2 2 4其他选项 三 应用 3 1 启动进程 3 1 1 强制启动 3 1 2 默认启
  • linux kill -9 杀不掉的进程

    kill 9 发送SIGKILL信号给进程 xff0c 将其终止 xff0c 但对于以下两种情况不适用 1 该进程是僵尸进程 xff08 STAT z xff09 xff0c 此时进程已经释放所有的资源 xff0c 但是没有被父进程释放 僵
  • 划分子网例题详解

    划分子网例题详解 网络基础考试题目 1 xff0c 假设取得网络地址200 200 200 0 xff0c 子网掩码为255 255 255 0 现在一个子网有100台主机 xff0c 另外4个子网有20台主机 xff0c 请问如何划分子网
  • ssh无秘钥登录报错sign_and_send_pubkey: signing failed: agent refused operation

    ssh连接远程主机时 xff0c 出现 sign and send pubkey signing failed agent refused operation 错误 xff0c 并且还是需要输入密码 表示ssh agent 已经在运行了 x
  • Linux开启路由转发功能

    标记一下 xff0c 今天想让一台Red Hat Enterprise Linux 7开通iptables的nat转发功能 xff0c 找了半天 A服务器 xff1a 192 168 30 20 24 B服务器 xff1a 192 168

随机推荐

  • E: Some index files failed to download. They have been ignored, or old ones used instead.解决方案

    1 删除 var lib apt lists 所有文件 sudo rm var lib apt lists vf 有文件夹不能删除的话使用 sudo rm rf var lib apt lists sudo rm var lib apt l
  • Microsoft Windows Vista

    Microsoft Windows Vista是微软Windows操作系统的最新版本 xff0c 于2005年7月22日微软正式公布了这一名字 原代号为Longhorn Windows Vista的内部版本是6 0 xff08 即Windo
  • tcp retransmission原因

    TCP协议是一个可靠的协议 它通过重新发送 retransmission 来实现TCP片段传输的可靠性 简单的说 xff0c TCP会不断重复发送TCP片段 xff0c 直到片段被正确接收 TCP片段丢失 TCP头部的checksum 接收
  • 数据库死锁原因及解决办法

    死锁 xff08 Deadlock xff09 所谓死锁 xff1a 是指两个或两个以上的进程在执行过程中 xff0c 因争夺资源而造成的一种互相等待的现象 xff0c 若无外力作用 xff0c 它们都将无法推进下去 此时称系统处于死锁状态
  • spring和springmvc父子容器的关系

    大家都知道 xff0c 在spring的配置中要分开配置service层的注解扫描 xff0c 以及springmvc变现层的注解扫描 xff0c 如下 xff1a lt 扫描加载Service实现类 gt lt context compo
  • pageHelper分页插件实现原理及使用方法

    插件官方网站 xff1a https github com pagehelper Mybatis PageHelper tree master src main java com github pagehelper 实现原理 xff1a 使
  • 虚拟机Linux系统安装nginx服务器并启动的步骤

    工作前的准备 xff1a 1 装有Linux的虚拟机 2 nginx安装包 xff0c 注意是gz结尾的压缩文件 具体步骤1 xff1a 1 nginx安装环境 nginx是 C 语言开发 xff0c 建议在 linux 上运行 xff0c
  • 什么是反射机制,有什么作用

    1 反射机制定义 反射的概念是由Smith在1982年首次提出的 xff0c 主要是指程序可以访问 检测和修改其本身状态或行为的一种能力 在Java环境中 xff0c 反射机制允许程序在执行时获取某个类自身的定义信息 xff0c 例如熟悉和
  • 模块化建立项目流程(Maven聚合模块)

    先说项目使用Maven的好处 1 项目构建 Maven定义了软件开发的整套流程体系 xff0c 并进行了封装 xff0c 开发人员只需要指定项目的构建流程 xff0c 无需针对每个流程编写自己的构建脚本 2 依赖管理 除了项目构建 xff0
  • 如何在linux下判断web服务是否开启?

    对于web服务的开启的判断有以下几种常用方法 xff1a 1 端口查看 xff1a 本地 xff1a ss xff0c netstat xff0c lsof 1 2 3 4 5 6 7 8 9 10
  • git基本命令

    最近再写一些项目上传到github xff0c 所以要用到git命令 本地需要先安装git客户端 xff0c 然后指定一个git地址为本地仓库 然后右键git bash here打开git命令界面 首先服务端需要创建一个项目以便clone到
  • jps查看Java线程,jstack查看具体线程堆状态

    想要使用jps需要配置环境变量 xff0c 在classpath后在加一个指定Java bin目录 具体命令如下 t2挂起了 xff0c 堆里面显示t2为RUNNABLE xff0c suspend xff0c resume废弃使用 IBM
  • python之ssh连接

    paramiko是用python语言写的一个模块 xff0c 遵循SSH2协议 xff0c 支持以加密和认证的方式 xff0c 进行远程服务器的连接 跟常用软件xshell xftp功能一样 xff0c 但是可以连接多台服务器 xff0c
  • 记录一个类加载变量引发的问题

    类加载变量导致的问题 类加载变量导致的问题 类加载变量导致的问题 因为项目需要 xff0c 银行要求使用weblogic部署并且启动所有项目 xff0c 不允许项目单独开服务启动一般都有这样的要求 xff0c 我所在的项目组有两个单独mai
  • lottie库动画方案

    什么是lottie Lottie是一个库 xff0c 可以解析使用AE制作的动画 xff08 需要用bodymovin导出为json格式 xff09 xff0c 支持web ios android和react native 在web侧 xf
  • for 循环嵌套性能的比较

    有人对着汇编语言不够一屑 xff0c 认为那已经是古老的低级语言 xff0c 是当今的非主流语言 xff0c 学了也不知道有什么用 是的 xff0c 我们不得不承认 xff0c 作为一门古老的语言 xff0c 汇编已经完成了历史赋予它的使命
  • Windows PowerShell打开方法与常用命令

    Windows PowerShell 是一种命令行外壳程序和脚本环境 xff0c 使命令行用户和脚本编写者可以利用 NET Framework 的强大功能 本文来介绍一下它的打开方法和常用的命令 启动方式 Win10系统可以在Cortana
  • Python实现微信自动回复

    先安装 itchat requests itchat uos itchat uos主要解决微信提示禁止网页登录导致登录失败的问题 以下有三种可玩方式 xff1a 1 回复好友 源代码如下 xff1a wechat autoreply imp
  • 体验华为操作系统 openEuler 20.03 LTS linux

    安装华为linux openEuler 20 03 LTS 一直在用centos xff0c 但redhat马上不再对其支持更新了 xff0c 刚好华为发行了社区版linux xff08 ps 难道是centos倒下 xff0c 华为ope
  • c++实现的阻塞队列

    阻塞队列 block queue 什么是阻塞队列 xff1a 在多线程编程时当有多个线程访问一个队列时如果队列为空 xff0c 则获取队列中元素的方法就会阻塞 xff0c 直到队列中有元素可以获取 解决的问题 xff1a 队列的线程安全问题