当前位置: 首页 > news >正文

【Linux】线程安全-生产者消费者模型

文章目录

  • 生产者消费者模型
    • 123规则
    • 应用场景
    • 优点
      • 忙闲不均
      • 生产者和消费者解耦
      • 支持高并发
    • 代码模拟

生产者消费者模型

123规则

1个线程安全的队列:只要保证先进先出特性的数据结构都可以称为队列

这个队列要保证互斥(就是保证当前只有一个线程对队列进行操作,其他线程不可以同时来操作),还要保证同步,当生产者将队列中填充满了之后要通知消费者来进行消费,消费者消费之后通知生产者来进行生产。
队列起到了生产者和消费者的缓冲作用,生产者不用因为没有人消费发愁,只需要将生产的数据放到队列中即可;消费者不用因为生产者生产了大量数据而发愁,只需要正常关注正在处理的数据即可

2个角色的线程:生产者和消费者

3个规则:生产者和生产者互斥、消费者和消费者互斥、生产者和消费者互斥+同步

应用场景

比如说微信的后台程序:在不同的场景下一个进程可以是消费者也可以是生产者
在这里插入图片描述

优点

忙闲不均

在同一时刻可能接收消息的线程不忙而处理消息的线程一直处于工作状态

生产者和消费者解耦

生产者只关心生产,关心队列是否有空闲空间;

消费者只关心消费,关心队列中是否有数据可用。

生产者和消费者不是串行的执行(串行的处理就是当一个线程接收到消息后才可以处理消息,并且只有处理完了之后才可以发送消息,是一个串行的过程),而生产者消费者模型将生产者和消费者解耦,接收消息的一辈子就接收消息,处理消息的一辈子就处理消息,发送消息一辈子就只发送消息,不受其他线程的影响

支持高并发

同一时刻多个人发送消息这种情况是支持的,因为接收消息的线程只需要接收消息,不用干其他事情,所以接收线程接收消息的速度很快

代码模拟

采用互斥和同步实现:

#include<stdio.h>
#include<iostream>
#include<queue>
#include<unistd.h>
#include<pthread.h>
using namespace std;
#define THREAD_COUNT 1//生产者和消费者数量
//创建线程安全队列
class RingQueue{
public:RingQueue(){capacity = 1;pthread_mutex_init(&que_lock, NULL);pthread_cond_init(&consum_cond, NULL);pthread_cond_init(&product_cond, NULL);}~RingQueue(){pthread_mutex_destroy(&que_lock);pthread_cond_destroy(&consum_cond);pthread_cond_destroy(&product_cond);}//往队列中放数据,生产void Push(int data){pthread_mutex_lock(&que_lock);while(que.size()>=capacity){pthread_cond_wait(&product_cond, &que_lock);//为什么要用while循环呢?//因为当生产者被唤醒后,需要再次判断队列是否可以满足生产的条件//生产者或者消费者都是需要在等待结束后再次判断的}que.push(data);//生产,往队列中放入数据cout<<"I am product: " << pthread_self() << "I product number is " << data << endl;pthread_mutex_unlock(&que_lock);pthread_cond_signal(&consum_cond);//生产者完成生产后唤醒消费者线程让消费者进行消费}//从队列中取数据,消费int Pop(){pthread_mutex_lock(&que_lock);while(que.size() <= 0){pthread_cond_wait(&consum_cond, &que_lock);}int data = que.front();que.pop();cout<<"I am consume: " << pthread_self() << "I consume number is " << data << endl;pthread_mutex_unlock(&que_lock);pthread_cond_signal(&product_cond);//消费者线程消费之后通知生产者来生产return data;}private:queue<int> que;//线程安全的队列//给队列一把锁,保证互斥,保证同一时刻只有一个线程对队列进行操作pthread_mutex_t que_lock;//同步的条件变量,队列有元素,消息,没有元素等待,唤醒生产者//保证生产者在队列中没有元素的时候进行生产(插入元素)pthread_cond_t consum_cond;pthread_cond_t product_cond;int capacity;//队列容量,队列元素大于容量表示队满,不再往里插入元素
};
int g_val = 0;
pthread_mutex_t g_val_lock = PTHREAD_MUTEX_INITIALIZER;//静态初始化保护g_val的互斥锁
void* product_thread_start(void* arg){RingQueue *q = (RingQueue*)arg;while(1){pthread_mutex_lock(&g_val_lock);//获取g_val的互斥锁q->Push(g_val);g_val++;sleep(1);pthread_mutex_unlock(&g_val_lock);}
}
void* consum_thread_start(void* arg){RingQueue *q = (RingQueue*)arg;while(1){q->Pop();}
}
int main(){pthread_t consum_tid[THREAD_COUNT];pthread_t product_tid[THREAD_COUNT];RingQueue* q = new RingQueue();for(int i=0; i<THREAD_COUNT; ++i){int ret = pthread_create(&consum_tid[i], NULL, consum_thread_start, (void*)q);if(ret < 0){perror("pthread_create");return 0;}ret = pthread_create(&product_tid[i], NULL, product_thread_start, (void*)q);if(ret < 0){perror("pthread_create");return 0;}}for(int i=0; i<THREAD_COUNT; ++i){pthread_join(consum_tid[i], NULL);pthread_join(product_tid[i], NULL);}delete q;return 0;
}

执行结果:

在这里插入图片描述

可以看到有效的控制了生产者和消费者的消费顺序,当生产者生产一个消费者就消费一个,消费者消费后生产者接着生产

相关文章:

【Linux】线程安全-生产者消费者模型

文章目录 生产者消费者模型123规则应用场景优点忙闲不均生产者和消费者解耦支持高并发 代码模拟 生产者消费者模型 123规则 1个线程安全的队列&#xff1a;只要保证先进先出特性的数据结构都可以称为队列 这个队列要保证互斥&#xff08;就是保证当前只有一个线程对队列进行操…...

优化(2) 2023/09/03

今天重新温习了下clean abap&#xff0c;以前只是偶尔打开看几眼。今天把有些自己不熟悉的地方&#xff0c;重点研究了下。有几个点可以在以后工作使用。这几点可能并不能提升程序效率&#xff0c;但会大大提高代码可读性和代码的可扩展性&#xff1a; 用insert XXX into tabl…...

Swap and Reverse 题解

Swap and Reverse 题面翻译 题目描述 本题共有 t t t 组数据。 给定一个长度为 n n n 的字符串 s s s 和一个整数 k k k&#xff0c; s s s 只包含小写字母&#xff0c;你可以进行若干次操作&#xff08;可以是零次&#xff09;&#xff0c;具体操作如下&#xff1a; 选…...

单元测试:优雅编写Kotlin单元测试

一、MockK简介 MockK是一款功能强大、易于使用的Kotlin mocking框架。在编写单元测试时&#xff0c;MockK能够帮助我们简化代码、提高测试覆盖率&#xff0c;并改善测试的可维护性。除了基本用法外&#xff0c;MockK还提供了许多额外的功能和灵活的用法&#xff0c;让我们能够…...

深度学习入门教学——卷积神经网络CNN

目录 一、CNN简介 一、输入层 二、卷积层 三、池化层 四、全连接层 一、CNN简介 1、应用领域 检测任务 分类与检索 超分辨率重构 2、卷积网络与传统网咯的区别 传统神经网络和卷积神经网络都是用来提取特征的。神经网络&#xff1a; 可以将其看作是一个二维的。卷积神经…...

【MySQL】MySQL系统变量(system variables)列表(mysqld --verbose --help的结果例)

文章目录 【MySQL】MySQL系统变量&#xff08;system variables&#xff09;列表&#xff08;mysqld --verbose --help的结果例&#xff09;mysqld --verbose --help的结果例参考 【免责声明】文章仅供学习交流&#xff0c;观点代表个人&#xff0c;与任何公司无关。 编辑|SQL和…...

Python学习之四 数据输入与输出

(一) 脚本编程 前面的章节,组要学习了一些简单的Python编程,使用的是交互式解释器,本章节将开始进行脚本编程。可以使用多种编辑器或者IDE完成编码,主要使用vim。 参考前续小节的写法,我们给a、b分别赋值3和5。 在终端运行程序后发现,没有任何输出。这就是本次我们将要…...

VBA技术资料MF51:VBA_在Excel中突出显示唯一值

【分享成果&#xff0c;随喜正能量】世间万物&#xff0c;因果循环不休&#xff0c;你的善心善行&#xff0c;都可能成为你的善缘善果。每天忆佛念佛&#xff0c;每天都在佛菩萨的加持下生活&#xff0c;自然吉祥如意&#xff0c;法喜充满。 。 我给VBA的定义&#xff1a;VBA是…...

Mqtt学习笔记--交叉编译移植(1)

简述 Mqtt目前在物联网行业的应用比较多&#xff0c;mqtt属于应用层的一个中间件&#xff0c;这个中间件实现消息的订阅发布机制。网上介绍Mqtt的实现原来的比较多&#xff0c;这里不细介绍。 其实在我们之前的产品中&#xff0c;自己也开发的有类似的中间件&#xff0c;除了具…...

Gateway的服务网关

Gateway服务网关 Gateway网关是我们服务的守门神&#xff0c;所有微服务的统一入口。 网关的核心功能特性&#xff1a; 请求路由 权限控制 限流 架构如下&#xff1a; gateway使用 引入依赖 创建gateway服务&#xff0c;引入依赖 <!--网关--> <dependency>…...

信息化发展18

存储技术 1 、存储分类 2 、常用存储模式的技术与应用对比&#xff1a; ( 1 &#xff09; 存储虚拟化&#xff08; Storage Virtualization &#xff09; 是“ 云存储” 的核心技术之一。 它带给人们直接的好处是提高了存储利用率&#xff0c; 降低了存储成本&#xff0c; 简…...

TypeScript学习 + 贪吃蛇项目

TypeSCript简介 TypeScript是JavaScript的超集。它对JS进行了扩展&#xff0c;向JS中引入了类型的概念&#xff0c;并添加了许多新的特性。TS代码需要通过编译器编译为JS&#xff0c;然后再交由JS解析器执行。TS完全兼容JS&#xff0c;换言之&#xff0c;任何的JS代码都可以直…...

YOLO-NAS详细教程-介绍如何进行物体检测

对象检测是计算机视觉中的一项核心任务,可以检测和分类图像中的边界框。自从深度学习首次取得突破以来,它就以极快的速度获得普及和普及,并推动了医疗领域、监控、智能购物等众多公司的发展。考虑到它最终满足了两个基本需求,这一点也就不足为奇了端到端方式:找到所有当前…...

容器没有命令时,如何查看进程、容器executable file not found in $PATH: unknown

前言 当容器没有ps -ef命令时&#xff0c;可以通过以下的命令来查看容器的进程。 docker container top查看容器运行的进程&#xff08;该命令很有用&#xff09; #docker container top 命令用于查看容器运行的进程 #当容器里面没有ps -ef命令时&#xff0c;使用docker con…...

如何使用 Amazon EMR 在 Amazon EKS 上构建可靠、高效、用户友好的 Spark 平台

这是 SafeGraph 技术主管经理 Nan Zhu 与亚马逊云科技高级解决方案架构师 Dave Thibault 共同撰写的特约文章。 SafeGraph 是一家地理空间数据公司&#xff0c;管理着全球超过 4100 万个兴趣点&#xff08;POI&#xff0c;Point of Interest&#xff09;&#xff0c;提供品牌隶…...

国产IDE如何获得捐赠和风险投资

有人在开发VB6 脚本工具&#xff0c;有人在开发VB6的插件&#xff0c;把VB6变成VSCODE界面模式&#xff0c;再加上NUGET&#xff0c;NPM等包管理器原理的在线组件、源码下载功能。 还有TWINBASIC几乎80%代替了VB6&#xff0c;radbasic一直封闭&#xff0c;听说也收到了不少众筹…...

【数学建模】清风数模正课5 相关性分析

相关系数 相关性分析的关键是计算相关系数&#xff0c;在本节课中将会介绍两种常用的相关系数&#xff1a;皮尔逊相关系数&#xff08;Pearson&#xff09;和斯皮尔曼相关系数&#xff08;Spearman&#xff09;。 它们可以用来衡量两个变量间相关性的大小&#xff0c;对于不同…...

Java设计模式:一、六大设计原则-03:里氏替换原则

文章目录 一、定义&#xff1a;里氏替换原则1.1 里氏替换原则1.2 里氏替换原则的作用 二、模拟场景&#xff1a;里氏替换原则三、违背方案&#xff1a;里氏替换原则3.1 工程结构3.2 储蓄卡和信用卡3.2.1 储蓄卡3.2.2 信用卡 3.3 单元测试3.3.1 储蓄卡测试3.3.2 信用卡测试 四、…...

jmeter 固定定时器

固定定时器&#xff08;Constant Timer&#xff09;是一个定时器元件&#xff0c;可以在线程组中的每个线程之间添加固定的延迟时间。固定定时器会对每个线程的执行进行一定的暂停。 聊一下和线程组中的调度器对线程组执行时长的影响&#xff1a; 相同&#xff1a; 都会影响线…...

【微服务部署】07-调用链追踪

文章目录 集成SkyWalking实现调用链追踪1. SkyWalking架构图2. 代码集成SkyWalking 集成SkyWalking实现调用链追踪 1. SkyWalking架构图 Receiver是SkyWalking的入口&#xff0c;支持gRPC和HTTP协议。 SkyWalking内部有分析和查询两个部分 存储方面SkyWalking支持Elasticsearc…...

HTML 语义化

目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案&#xff1a; 语义化标签&#xff1a; <header>&#xff1a;页头<nav>&#xff1a;导航<main>&#xff1a;主要内容<article>&#x…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

Java - Mysql数据类型对应

Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

selenium学习实战【Python爬虫】

selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

LeetCode - 199. 二叉树的右视图

题目 199. 二叉树的右视图 - 力扣&#xff08;LeetCode&#xff09; 思路 右视图是指从树的右侧看&#xff0c;对于每一层&#xff0c;只能看到该层最右边的节点。实现思路是&#xff1a; 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析

Linux 内存管理实战精讲&#xff1a;核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用&#xff0c;还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...

深度学习水论文:mamba+图像增强

&#x1f9c0;当前视觉领域对高效长序列建模需求激增&#xff0c;对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模&#xff0c;以及动态计算优势&#xff0c;在图像质量提升和细节恢复方面有难以替代的作用。 &#x1f9c0;因此短时间内&#xff0c;就有不…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...