当前位置: 首页 > 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…...

B站App反Frida检测实战:手把手教你绕过libmsaoaidsec.so的线程创建检测

B站App高级反调试对抗&#xff1a;深入解析libmsaoaidsec.so的Frida检测与绕过技术 在移动安全研究领域&#xff0c;应用加固与逆向分析始终是一场永不停歇的攻防博弈。作为国内领先的视频平台&#xff0c;B站App采用了多层次的反调试机制保护其核心业务逻辑&#xff0c;其中li…...

自然语言生成跟进记录、自然语言生成预约登记功能

在企业数字化转型的深化阶段&#xff0c;客户关系管理&#xff08;CRM&#xff09;作为连接企业与客户的核心环节&#xff0c;其运营效率直接影响业务推进节奏。传统CRM操作中&#xff0c;手动撰写跟进记录、录入预约登记的重复性工作&#xff0c;不仅耗费大量人力时间&#xf…...

AceTimeClock嵌入式时间同步框架深度解析

1. AceTimeClock 库深度技术解析&#xff1a;嵌入式系统高精度时间同步的工程实践在嵌入式系统开发中&#xff0c;时间管理远非简单的millis()或micros()调用。一个健壮的时钟子系统必须同时满足高精度、高可靠性、低功耗、跨平台兼容性以及故障容错能力。AceTimeClock 库正是为…...

如何在PS4上轻松管理游戏存档?Apollo Save Tool终极指南

如何在PS4上轻松管理游戏存档&#xff1f;Apollo Save Tool终极指南 【免费下载链接】apollo-ps4 Apollo Save Tool (PS4) 项目地址: https://gitcode.com/gh_mirrors/ap/apollo-ps4 还在为PS4游戏存档管理发愁吗&#xff1f;&#x1f914; 每次换主机都要重新开始&…...

别再只做相关性分析了!用Python的CausalNex库5分钟上手因果图建模

别再只做相关性分析了&#xff01;用Python的CausalNex库5分钟上手因果图建模 数据分析领域长期存在一个经典误区&#xff1a;将相关性等同于因果性。我们经常看到这样的结论——"冰淇淋销量增加导致溺水事件上升"&#xff0c;这显然忽略了温度这一共同原因。传统机器…...

从数学推导到5G落地:用NumPy复现LS/MMSE信道估计算法的完整指南

从数学推导到5G落地&#xff1a;用NumPy复现LS/MMSE信道估计算法的完整指南 在5G通信系统的设计与优化中&#xff0c;信道估计始终是决定系统性能的关键环节。想象一下&#xff0c;当你用手机观看4K视频时&#xff0c;那些流畅的画面背后&#xff0c;正是无数个精密的算法在实时…...

OpenClaw技能开发入门:为Qwen3-32B定制Markdown文档处理器

OpenClaw技能开发入门&#xff1a;为Qwen3-32B定制Markdown文档处理器 1. 为什么需要定制Markdown处理器&#xff1f; 去年我在整理技术文档时遇到了一个典型问题&#xff1a;团队协作产生的Markdown文件格式混乱&#xff0c;有的使用空格缩进&#xff0c;有的用Tab&#xff…...

Arduino嵌入式日志框架:零堆分配与编译期裁剪设计

1. 项目概述ArduinoLog 是一款专为 Arduino 及兼容嵌入式平台设计的轻量级 C 日志框架&#xff0c;其核心目标是在资源受限的微控制器环境中提供高可控性、零动态内存分配、低运行时开销的日志能力。它并非简单封装Serial.print()的工具&#xff0c;而是借鉴 log4j、log4cpp 等…...

Z-Image-Turbo_Sugar脸部Lora惊艳效果:发丝边缘柔化与面部光影层次表现

Z-Image-Turbo_Sugar脸部Lora惊艳效果&#xff1a;发丝边缘柔化与面部光影层次表现 如果你正在寻找一款能生成极具氛围感、细节精致的“甜妹”风格人像的AI模型&#xff0c;那么Z-Image-Turbo_Sugar脸部Lora绝对值得你花时间体验。它不仅仅是一个简单的文生图工具&#xff0c;…...

Can协议(一)

CAN设备&#xff08;如CAN盒&#xff09;上常见的 ‌PWR&#xff08;Power&#xff09;‌、‌ERR&#xff08;Error&#xff09;‌ 和 ‌CAN‌ 三个指示灯&#xff0c;其含义如下&#xff1a; 1.PWR&#xff08;电源指示灯&#xff09;‌ PWR是电源指示灯&#xff0c;表示设备是…...