Linux-生产者与消费者模型

文章目录

  • 一、什么是生产者与消费者模型?
  • 二、示例模型
    • 示例模型介绍
    • 交易场所(blockQueue)
    • 消费者与生产者
    • 运行结果
  • 总结


一、什么是生产者与消费者模型?

参照日常生活中,购买商品的人群可以被称之为消费者,生产商品的工厂可以被称之为生产者,而在两者之间还存在超市被称之为交易场所。 它们还存在三种关系,生产者与生产者之间是互斥关系,消费者与消费者之间也是互斥关系,消费者与生产者存在互斥/同步关系。这三种关系在多线程有着重要体现,通过我们之前所学习的互斥锁和条件变量可以反映这三种关系。

今天我们就需要用我们的多线程知识来构建一个简单的生产者与消费者模型。

二、示例模型

示例模型介绍

该模型由生产者线程随机生成(生产)两个随机数,消费者线程来进行对两个随机数进行计算(消费), 而我们的交易场所就由队列(queue)来充当。

生产者不断往队列放数据,消费者不断从队列拿数据,但是队列总有满/空的时候,所以我们就要严格控制他们的互斥/同步!

交易场所(blockQueue)

	blockQueue.hpp
#pragma once
#include <iostream>
#include <cstdio>
#include <unistd.h>
#include <pthread.h>
#include <queue>
#include "Task.hpp"
#include "lockGuard.hpp"
const int df_cap = 5;template <class Data>
class blockQueue
{
public:blockQueue(int capacity = df_cap): _capacity(capacity){//初始化pthread_cond_init(&_empty, nullptr);pthread_cond_init(&_full, nullptr);pthread_mutex_init(&_mutex, nullptr);}bool isEmpty(){return _queue.size() == 0;}bool isFull(){return _queue.size() == _capacity;}void push(const Data &data){pthread_mutex_lock(&_mutex);while (isFull()) //由于pthread_cond_wait函数存在申请锁失败的情况,所以我们要使用while循环检查队列是否为满pthread_cond_wait(&_full, &_mutex);_queue.push(data);pthread_cond_signal(&_empty);pthread_mutex_unlock(&_mutex);}void pop(Data *output){pthread_mutex_lock(&_mutex);while (isEmpty())//由于pthread_cond_wait函数存在申请锁失败的情况,所以我们要使用while循环检查队列是否为空pthread_cond_wait(&_empty, &_mutex);*output = _queue.front();_queue.pop();pthread_cond_signal(&_full);pthread_mutex_unlock(&_mutex);}~blockQueue(){pthread_cond_destroy(&_empty);pthread_cond_destroy(&_full);pthread_mutex_destroy(&_mutex);}private:std::queue<Data> _queue;int _capacity;pthread_cond_t _empty;pthread_cond_t _full;pthread_mutex_t _mutex;
};

该blockQueue主要是对队列进行一个封装,因为STL提供的容器一般都不是线程安全的,所以需要自己进行封装使它成为一个可重入的类型。

	Task.hpp
#pragma once
#include <iostream>
#include <functional>class Task
{
public:typedef std::function<int(int, int)> func_t;Task() {}Task(int x, int y, func_t func): _func(func), _x(x), _y(y){}int operator()(){return _func(_x, _y);}int getelement1(){return _x;}int getelement2(){return _y;}private:int _x;int _y;func_t _func;
};

消费者与生产者

#include "blockQueue.hpp"
#include <ctime>#define P_TNUM 1
#define C_TNUM 5void *consumer(void *args)
{blockQueue<Task> *queue = (blockQueue<Task> *)args;while (1){// sleep(1);Task tmp;queue->pop(&tmp);std::cout << pthread_self() << "获取结果: " << tmp.getelement1() << " + " << tmp.getelement2() << " = " << tmp() << std::endl;}return nullptr;
}void *productor(void *args)
{blockQueue<Task> *queue = (blockQueue<Task> *)args;while (1){int x = rand() % 100 + 1;usleep(1000);int y = rand() % 10 + 1;Task task(x, y, [](const int x, const int y) -> int{ return x + y; }); //lambda表达式queue->push(task);std::cout << pthread_self() << "生产数据: " << task.getelement1() << " + " << task.getelement2() << " = ? " << std::endl;sleep(1);}return nullptr;
}int main()
{srand((unsigned int)time(nullptr) ^ 0xfffffff ^ 0x12345678);pthread_t parr[P_TNUM], carr[C_TNUM];blockQueue<Task> *queue = new blockQueue<Task>;for (int i = 0; i < P_TNUM; i++){pthread_create(parr + i, nullptr, productor, (void *)queue);}sleep(1);for (int i = 0; i < C_TNUM; i++){pthread_create(carr + i, nullptr, consumer, (void *)queue);}for (int i = 0; i < P_TNUM; i++){pthread_join(parr[i], nullptr);}for (int i = 0; i < C_TNUM; i++){pthread_join(carr[i], nullptr);}delete queue;return 0;
}

运行结果

在这里插入图片描述


总结

本章主要检验自身多线程学习的成果,灵活运用了线程互斥和条件变量的接口函数,大家下来可以自己尝试写一遍。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mongodb文档数据建模

基础建模 内嵌方法和数组方完成关系表述 内嵌一对一关系建模 数组内嵌一对N 关系建模 数组内嵌对象多对多关系建模 文档模型设计之二&#xff1a;工况细化 join 查询 不支持外键 设计模式集锦 版本迭代加schema_version 字段 频繁写入改为时间区间写入 聚合变预聚合方式 采用…

预约陪诊APP定制开发方案以及流程详解

随着医疗行业的快速发展&#xff0c;越来越多的人开始关注自己的健康问题。然而&#xff0c;在看病的过程中&#xff0c;很多人都会感到孤独和无助。为了解决这个问题&#xff0c;许多医疗机构和企业推出了预约陪诊APP,旨在为用户提供一个安全、便捷的陪伴服务。本文将详细介绍…

爱普生EPSON全新传感技术方案亮相高交会,创造新时代“精智生活”

2023年中国国际高新技术成果交易会在深圳福田会展中心盛大举行&#xff0c;是目前中国规模最大、最具影响力的科技类展会之一。爱普生作为始终坚持“科技本地化”战略的技术创新前沿企业参与此次展会&#xff0c;为中国用户带来爱普生电子元器件三款创新技术与四大成熟传感器解…

elk收集k8s微服务日志

一、前言 使用filebeat自动发现收集k8s的pod日志&#xff0c;这里分别收集前端的nginx日志&#xff0c;还有后端的服务java日志&#xff0c;所有格式都是用json格式&#xff0c;建议还是需要让开发人员去输出java的日志为json&#xff0c;logstash分割java日志为json格式&#…

SQLiteC/C++接口详细介绍sqlite3_stmt类(十二)

返回&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;SQLiteC/C接口详细介绍sqlite3_stmt类&#xff08;十一&#xff09; 下一篇&#xff1a; SQLiteC/C接口详细介绍sqlite3_stmt类&#xff08;十三&#xff09; 48、sqlite3_stmt_isexplain sqlite3_stmt_is…

【前端寻宝之路】学习和总结HTML的标签属性

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法|MySQL| ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-tgsZb9zTBxJHHYhD {font-family:"trebuchet ms",verdana,arial,sans-serif;f…

深度学习:复杂工业场景下的复杂缺陷检测方法

摘要&#xff1a;在复杂的工业场景中&#xff0c;缺陷检测一直是一个重要而具有挑战性的任务。近年来&#xff0c;深度学习技术的快速发展为复杂工业场景下的缺陷检测提供了新的解决方案。本文将介绍深度学习在复杂工业场景下的复杂缺陷检测中的应用&#xff0c;并探讨其技术进…

vue2 脚手架

安装 文档&#xff1a;https://cli.vuejs.org/zh/ 第一步&#xff1a;全局安装&#xff08;仅第一次执行&#xff09; npm install -g vue/cli 或 yarn global add vue/cli 备注&#xff1a;如果出现下载缓慢&#xff1a;请配置npm 淘宝镜像&#xff1a; npm config set regis…

使用CSS3画出一个叮当猫HTML源码

我们经常使用PS或者Flash制作动画&#xff0c;本文则介绍了如何用CSS3画出个叮当猫&#xff0c;实现过程很有趣&#xff0c;感兴趣的朋友可以参考一下 首先&#xff0c;先把HTML结构搭建好&#xff1a; <div class"wrapper"> <!--叮当猫整体--> <di…

【使用redisson完成延迟队列的功能】使用redisson配合线程池完成异步执行功能,延迟队列和不需要延迟的队列

1. 使用redisson完成延迟队列的功能 引入依赖 spring-boot-starter-actuator是Spring Boot提供的一个用于监控和管理应用程序的模块 用于查看应用程序的健康状况、审计信息、指标和其他有用的信息。这些端点可以帮助你监控应用程序的运行状态、性能指标和健康状况。 已经有了…

微信小程序 canvas层级过高覆盖原生组件

一、背景 微信小程序中使用signature第三方插件完成签名效果&#xff0c;但真机调试时发现canvas层级过高遮挡了按钮 二、具体问题 问题原因&#xff1a;签名后点击按钮无法生效 问题代码&#xff1a; <template><view class"sign_page" v-cloak>&l…

排序算法记录(冒泡+快排+归并)

文章目录 前言冒泡排序快速排序归并排序 前言 冒泡 快排 归并&#xff0c;这三种排序算法太过经典&#xff0c;但又很容易忘了。虽然一开始接触雀氏这些算法雀氏有些头大&#xff0c;但时间长了也还好。主要是回忆这些算法干了啥很耗时间。 如果在笔试时要写一个o(nlogn)的…

React【Day1】

B站视频链接 一、React介绍 React由Meta公司开发&#xff0c;是一个用于 构建Web和原生交互界面的库 React的优势 相较于传统基于DOM开发的优势 组件化的开发方式不错的性能 相较于其它前端框架的优势 丰富的生态跨平台支持 React的市场情况 全球最流行&#xff0c;大…

基于modbus TCP实现EPICS与西门子S7 1200系列1215C PLC的通信

PLC介绍 西门子系列PLC在国内的市场占比第一&#xff0c;1200系列中小型PLC&#xff0c;因其众多的产品序列、强大的通讯功能和丰富扩展模块&#xff0c;被使用在工业生产、自动化生产线、智能制造、机器人等各行各业。根据CPU的供电电源的型号和数字量输出的类型&#xff0c;…

基于飞凌嵌入式i.MX6ULL核心板的电梯智能物联网关方案

电梯是现代社会中不可或缺的基础性设施&#xff0c;为人们的生产生活提供了很大的便捷。我国目前正处于城镇化的快速发展阶段&#xff0c;由此带动的城市基础设施建设、楼宇建设、老破小改造等需求也让我国的电梯行业处在了一个高速增长期。截至2023年年底&#xff0c;中国电梯…

蓝桥杯练习题——健身大调查

在浏览器中预览 index.html 页面效果如下&#xff1a; 目标 完成 js/index.js 中的 formSubmit 函数&#xff0c;用户填写表单信息后&#xff0c;点击蓝色提交按钮&#xff0c;表单项隐藏&#xff0c;页面显示用户提交的表单信息&#xff08;在 id 为 result 的元素显示&#…

开源模型应用落地-安全合规篇-模型输出合规性检测(三)

一、前言 为什么我们需要花大力气对用户输入的内容和模型生成的输出进行合规性检测,一方面是严格遵守各项法规要求,具体如下:互联网信息服务深度合成管理规定https://www.gov.cn/zhengce/zhengceku/2022-12/12/content_5731431.htm ​ 其次,受限于模型本身的一些缺陷,…

leetcode 225.用队列实现栈 JAVA

题目 思路 1.一种是用双端队列&#xff08;Deque&#xff09;&#xff0c;直接就可以调用很多现成的方法&#xff0c;非常方便。 2.另一种是用普通的队列&#xff08;Queue&#xff09;,要实现栈的先入后出&#xff0c;可以将最后一个元素的前面所有元素出队&#xff0c;然后…

【图解物联网】第2章 物联网的架构

2.1 物联网的整体结构 实现物联网时&#xff0c;物联网服务大体上发挥着两个作用。 第一是把从设备收到的数据保存到数据库&#xff0c;并对采集的数据进行分析。 第二是向设备发送指令和信息。 本章将会为大家介绍如何构建物联网服务&#xff0c;以…

【Canvas与艺术】绘制暗绿色汽车速度仪表盘

【原型】 【成果】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>暗绿色汽车速度仪表盘</title><style type"t…