【Linux】cp问题,生产者消费者问题代码实现
文章目录
- 前言
- 一、 BlockQueue.hpp(阻塞队列)
- 二、main.cpp
前言
生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。这个阻塞队列就是用来给生产者和消费者解耦的。
一、 BlockQueue.hpp(阻塞队列)
在多线程编程中阻塞队列(Blocking Queue)是一种常用于实现生产者和消费者模型的数据结构。其与普通的队列区别在于,当队列为空时,从队列获取元素的操作将会被阻塞,直到队列中被放入了元素;当队列满时,往队列里存放元素的操作也会被阻塞,直到有元素被从队列中取出(以上的操作都是基于不同的线程来说的,线程在对阻塞队列进程操作时会被阻塞)
类似之前我们学过的管道
问:我们怎么知道我们要让一个线程去休眠了那?
答:一定是临界资源不就绪,没错,临界资源也是有状态的!!
问:你怎么知道临界资源是就绪还是不就绪的?你判断出来的!判断是访问临界资源吗?
答:必须是的,也就是判断必须在加锁之后!!
判断当前线程是否要进入等待,需要判断是否满足临界资源的条件
而我们判断临界资源本质是在访问临界区,所有这个操作只能在加锁之后
#pragma once
#include<iostream>
#include<queue>
#include<pthread.h>using namespace std;template<class T>class BlockQueue{const static int defaultnum=20;public:
BlockQueue(int maxcap=defaultnum):maxcap_(maxcap)
{pthread_mutex_init(&mutex_,nullptr);pthread_cond_init(&c_cond_,nullptr);pthread_cond_init(&p_cond_,nullptr);low_water_ = maxcap_/3;//消费到低于到这个数字时,就唤醒生产者生产high_water_ = (maxcap_*2)/3;//生产到这个数字时,就唤醒消费者过来消费
}void push(const T&in){pthread_mutex_lock(&mutex_);// 我们怎么知道我们要让一个线程去休眠了那?一定是临界资源不就绪,没错,临界资源也是有状态的!!// 你怎么知道临界资源是就绪还是不就绪的?你判断出来的!判断是访问临界资源吗?必须是的,也就是判断必须在加锁之后!!if(q.size()==maxcap_){//满了,则生产者就去休眠pthread_cond_wait(&p_cond_,&mutex_);// pthread_cond_wait让线程等待的时候,会自动释放锁!}// 1. 队列没满 2.被唤醒 q.push(in);// 你想生产,就直接能生产吗?不一定。你得先确保生产条件满足if(q .size() > high_water_) pthread_cond_signal(&c_cond_);//当产品数量大于high的时候唤醒消费者队列,让其过来消费pthread_mutex_unlock(&mutex_);
}T pop(){pthread_mutex_lock(&mutex_);//判断当前线程是否要进入等待,需要判断是否满足临界资源的条件//而我们判断临界资源本质是在访问临界区,所有这个操作只能在加锁之后if(q.size()==0){pthread_cond_wait(&c_cond_,&mutex_);}T out=q.front();// 你想消费,就直接能消费吗?不一定。你得先确保消费条件满足q.pop();if(q.size()<low_water_){pthread_cond_signal(&p_cond_ );}pthread_mutex_unlock(&mutex_);return out;
}~BlockQueue(){pthread_mutex_destroy(&mutex_);pthread_cond_destroy(&c_cond_);pthread_cond_destroy(&p_cond_);
}private:
int low_water_;//消费到低于到这个数字时,就唤醒生产者生产
int high_water_;//生产到这个数字时,就唤醒消费者过来消费
pthread_mutex_t mutex_;
pthread_cond_t c_cond_;//消费者的等待队列
pthread_cond_t p_cond_;//生产者的等待队列
queue<T>q;//共享资源
int maxcap_;//阻塞队列的最大容量
};
二、main.cpp
#include "BlockQueue.hpp"
#include <unistd.h>
#include <time.h>void *Customer(void *args)
{BlockQueue<int> *bq = static_cast<BlockQueue<int> *>(args);while (true){int n = bq->pop();cout << "Customer get " << n << endl;}
}void *Productor(void *args)
{BlockQueue<int> *bq = static_cast<BlockQueue<int> *>(args);srand((unsigned int)time(nullptr));int n = 0;// 产生随机数放入队列中while (true){sleep(1);n = rand() % 100 + 1;bq->push(n);cout << "Productor create n: " << n << endl;}
}int main()
{BlockQueue<int> *bq = new BlockQueue<int>();// 根据目标所需,创建存储不同类型的阻塞队列pthread_t c, p;pthread_create(&c, nullptr, Customer, bq); // 消费者线程pthread_create(&p, nullptr, Productor, bq); // 生产者线程pthread_join(c, nullptr);pthread_join(p, nullptr);return 0;
}
相关文章:

【Linux】cp问题,生产者消费者问题代码实现
文章目录 前言一、 BlockQueue.hpp(阻塞队列)二、main.cpp 前言 生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用…...

C++1114新标准——统一初始化(Uniform Initialization)、Initializer_list(初始化列表)、explicit
系列文章目录 C11&14新标准——Variadic templates(数量不定的模板参数) C11&14新标准——Uniform Initialization(统一初始化)、Initializer_list(初始化列表)、explicit 文章目录 系列文章目录1…...

Kubeadm 方式部署K8s集群
环境 主节点CPU核数必须是 ≥2核且内存要求必须≥2G,否则k8s无法启动 主机名地址角色配置kube-master192.168.134.165主节点2核4Gkube-node1192..168.134.166 工作节点2核4Gkube-node2192.168.134.163工作节点2核4G 1.获取镜像 谷歌镜像[由于国内网络原因…...
力扣376周赛
力扣第376场周赛 找出缺失和重复的数字 map模拟 class Solution { public:vector<int> findMissingAndRepeatedValues(vector<vector<int>>& grid) {int n grid.size() , m grid[0].size();map<int,int>mi;for(int i 0 ; i < n ; i ){for…...

SU渲染受到电脑性能影响大吗?如何提高渲染速度
一般3d设计师们在进行设计工作前都需要提供一台高配电脑,那么你这知道su渲染对电脑要求高吗?电脑带不动su怎么解决?su对电脑什么配件要求高?今天这篇文章就详细为大家带来电脑硬件对su建模渲染的影响,以及su渲染慢怎么…...

Docker - Android源码编译与烧写
创建源代码 并挂载到win目录 docker run -v /mnt/f/android8.0:/data/android8.0 -it --name android8.0 49a981f2b85f /bin/bash 使用 docker update 命令动态调整内存限制: 重新运行一个容器 docker run -m 512m my_container 修改运行中容器 显示运行中容器 d…...

股票价格预测 | Python实现基于ARIMA和LSTM的股票预测模型(含XGBoost特征重要性衡量)
文章目录 效果一览文章概述模型描述源码设计效果一览 文章概述 Python实现基于ARIMA和LSTM的股票预测模型(Stock-Prediction) Data ExtractionFormatting data for time seriesFeature engineering(Feature Importance using X...

Base64
1. Base64是什么? Base64(基底64)是一种基于64个可打印字符来表示二进制数据的表示方法。每6个比特为一个单元,对应某个可打印字符。3个字节相当于24个比特,对应于4个Base64单元,即3个字节可由4个可打印字…...
二叉搜索树的简单C++类实现
二叉搜索树(BST)是一种重要的数据结构,它对于理解树的操作和算法至关重要,其中序输出是有序的。本文通过C实现一个BST的类,并在插入和删除节点时提供清晰的输出,可视化这些操作的过程。 二叉搜索树的节点结…...

禁毒知识竞赛流程和规则
禁毒知识竞赛是一项全国性竞赛活动。有着深化全国青少年毒品预防教育,巩固学校毒品预防教育成果的重要作用。本文介绍一场禁毒知识竞赛的完整流程和规则,供单位组织此类活动时参考。 1、赛制 第一轮10进6,第二轮6进4,4支队伍决出…...

CSS 基础
文章目录 CSS 常见的属性CSS 常见样式行内样式内嵌样式导入样式 CSS 选择器标签选择器id选择器类选择器全局选择器属性选择器组合选择器 CSS 常见应用表格列表导航栏下拉菜单提示工具图片廊 CSS (Cascading Style Sheets,层叠样式表),是一种用…...

黑色翻页时钟HTML源码-倒计时单页翻页时钟
黑色翻页时钟HTML源码-倒计时单页翻页时钟这是一个类似fliqlo的黑色翻页时钟HTML源码,它仅包含一个HTML文件,上传到网站后即可使用。该时钟具有查看当前时间、秒表和倒计时功能,并且可以在页面的右下角进行设置。 红色动态炫酷数字时钟html网…...

2043杨辉三角(C语言)
目录 一:题目 二:思路分析 三:代码 一:题目 二:思路分析 1.通过杨辉三角,不难发现中间的数等于肩头两个数之和 2.但是当我们的输出结果,与杨辉三角的形式有所不同,但是我们可以找…...

【机器学习】从底层手写实现线性回归
【机器学习】Building-Linear-Regression-from-Scratch 线性回归 Linear Regression0. 数据的导入与相关预处理0.工具函数1. 批量梯度下降法 Batch Gradient Descent2. 小批量梯度下降法 Mini Batch Gradient Descent(在批量方面进行了改进)3. 自适应梯度…...
判断数组中对象的某个值是否有相同的并去重
如果你想判断数组中对象的某个值是否有相同的,并进行去重,你可以使用 JavaScript 中的一些数组方法和 Set 对象。以下是一个示例: // 原始数组包含对象 const array [{ id: 1, name: John },{ id: 2, name: Jane },{ id: 3, name: Doe },{ …...
Shell脚本 变量 语句 表达式
常见的解释器 #!/bin/sh #不推荐(了解) #!/bin/bash #!/usr/bin/python #!/bin/awk#!后跟的字符表示要启动的程序,该程序读取该文件执行。 #! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行shell 函数 myShellName () {command1 }函数调用…...

MIT6.S081-实验准备
实验全程在Vmware虚拟机 (镜像:Ubuntu-20.04-beta-desktop-amd64) 中进行 一、版本控制 1.1 将mit的实验代码克隆到本地 git clone git://g.csail.mit.edu/xv6-labs-2020 1.2 修改本地git配置文件 创建github仓库,记录仓库地址 我的仓库地址就是htt…...

工具在手,创作无忧:一键下载安装Auto CAD工具,让艺术创作更加轻松愉悦!
不要再浪费时间在网上寻找Auto CAD的安装包了!因为你所需的一切都可以在这里找到!作为全球领先的设计和绘图软件,Auto CAD为艺术家、设计师和工程师们提供了无限的创作潜力。不论是建筑设计、工业设计还是室内装饰,Auto CAD都能助…...
第25节: Vue3 带组件
在UniApp中使用Vue3框架时,你可以使用组件来封装可复用的代码块,并在需要的地方进行渲染。下面是一个示例,演示了如何在UniApp中使用Vue3框架使用带组件: <template> <view> <button click"toggleActive&q…...
ubuntu apache2配置反向代理
1.Ubuntu安装apache sudo apt-get update sudo apt-get install apache2 2.apache2反向代理配置 sudo vim /etc/apache2/sites-available/000-default.conf 添加内容如下: <VirtualHost *:80># The ServerName directive sets the request scheme, host…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...

idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...