基于ucos-ii操作系统的生产者消费者-问题

目  录

第1章 题目分析. 1

1.1 生产者线程... 1

1.2 消费者线程... 1

1.3 缓冲区... 1

1.4 进程的同步与互斥... 1

第2章 解决方案. 2

2.1 总体方案... 2

2.2 生产者问题... 2

2.3 消费者问题... 3

2.4 进程问题... 5

第3章 实验结果. 6

3.1 运行结果... 6

3.2 结果分析... 8

第4章 实验总结. 8

参考文献. 9

                                                                               

第1章 题目分析

在我的题目中,要求创建4个工厂同时生产一种商品,并由1个销售商进行销售。这是一个典型的生产者-消费者问题。经过查阅资料,我对这个问题有了一个初步的认识和分析。在uC/OS-II实时操作系统中,生产者-消费者问题是指多个任务之间共享一个有限缓冲区的情况下的同步与通信问题。生产者任务负责向缓冲区中放入数据,而消费者任务则负责从缓冲区中取出数据。这需要确保生产者和消费者之间的协调,避免生产者在缓冲区已满时继续生产,或者消费者在缓冲区为空时继续消费的问题。通过信号量来实现生产者与消费者之间的有效通信和同步。

1.1 生产者线程

    生产者线程是在生产者消费者问题中负责向共享缓冲区中放入数据的线程。其主要任务是生成数据,并将数据放入缓冲区中。生产者线程需要注意缓冲区的状态,当缓冲区已满时需要等待,直到有空间可以放入新的数据。为了实现线程间的同步与通信,生产者线程可以使用信号量同步机制来控制对共享资源的访问。

1.2 消费者线程

    消费者线程与生产者线程类似,是在生产者消费者问题中负责从共享缓冲区中取出数据的线程。主要作用是消耗数据,并将缓冲区中的数据取出,释放空间。消费者线程需要注意缓冲区的状态,当缓冲区为空时需要等待,直到有数据可供消费。与生产者线程相同,可以使用信号量同步。

1.3 缓冲区

    缓冲区相当于仓库,是在生产者消费者问题中用于存储数据的区域。用来在生产者和消费者之间传递数据。生产者负责向缓冲池中写入数据,而消费者则从中读取数据进行处理。缓冲区位置的空和缺会影响生产者和消费者线程的行为。

1.4 进程的同步与互斥

    为了使进程之间正确协调和共享资源,就需要进程的同步与互斥,进程的同步能够确保进程按照特定顺序执行,互斥则是确保在任何时刻只有一个进程可以访问共享资源,通过同步机制和互斥锁或信号量,确保进程间的安全交互和数据一致性。

在编写程序时,我创建了两个信号量,分别是mutex、empty、full、proCmutex。mutex用来控制对共享缓冲区的访问,初始值为1,此时表示共享资源可访问。也就是可以生产和销售产品。empty用来表示空闲的缓冲区空位的数量,初始值为缓冲区的大小,在我的实验中,这个值等于100。full用来表示已被生产者填充的缓冲区空位的数量,初始值为0,表示初始时没有产品可已消费。proCmutex用来控制生产者计数的访问,初始值为1,此时表示初始时生产者计数可以进行访问。

第2章 解决方案

2.1 总体方案

    为了完成从生产到销售这一完整的产业链,需要完成并协调生产工厂、仓库、销售商三个主要部分的工作,实验的总体思路非常明确。首先是4个生产商同时进行商品的生产,然后把生产的东西放入库存,最后由1个销售商进行销售即可。

图2-1 总体系统方案

2.2 生产者问题

    根据生产问题的逻辑关系,绘制图2-2的流程图。首先是生产系统的初始化,这里把商品的初始数量设置为0,然后开始生产商品,4个工厂一次同时生产1个商品,并将生产的商品放入缓冲区中,库存的最大数量是100,当生产的商品的数量大于100时,立即停止生产,并等待商品的销售;然后更新库存,再次判断库存的数量是否在合理范围内。

  1. void* producer(void* a) {  
  2.     while (true) {  
  3.         while (proCmutex <= 0);  
  4.         proCmutex--;  
  5.         proCount++;  
  6.         gc++;  
  7.         printf("[%d工厂生产一个傻妞\n",gc);  
  8.         if (gc >= 4) { gc = 0; }  
  9.         full++;  
  10.         printf("当前库存数量:%d\n", full);  
  11.         proCmutex++;  
  12.         while (empty <= 0) {  
  13.             printf("库存已满!\n");  
  14.             Sleep(2000);  }  
  15.         empty--;  
  16.         while (mutex <= 0);  
  17.         mutex--;  
  18.         buffer[in] = proCount;  
  19.         in = (in + 1) % N;  
  20.         mutex++;  
  21.         Sleep(sleepTime);  
  22.     }  }  

图2-2 生产者程序流程图

2.3 消费者问题

    消费系统和生产系统有相似之处,如图2-3所示,首先系统进入初始化,完成这一步后需要立即判断库存的数量,因为当未生产商品时是不能进行商品销售的。如果判断目前库存数量为空,则立即停止销售,等待生产系统生产商品,并更新库存,进入下一个循环;反之,如果判断目前库存数量不为空,则开始进行销售,并进入下一个条件判断。

  1. void* consumer(void* b) {  
  2.     while (true) {  
  3.         while (full <= 0) {  
  4.             printf("库存为空!\n");  
  5.         }  
  6.         full--;  
  7.         while (mutex <= 0);  
  8.         mutex--;  
  9.         int nextc = buffer[out];  
  10.         buffer[out] = 0; //消费完将缓冲区设置为0  
  11.         out = (out + 1) % N;  
  12.         mutex++;  
  13.         empty++;  
  14.         consCount++;  
  15.         printf("\t\t\t\t陆小千 销售一个傻妞\n");  
  16.         printf("\t\t\t\t已销售产品数量:%d\n", consCount);  
  17.         Sleep(sleepTime);  
  18.     }  
  19. }  


图2-3 消费者程序流程图

2.4 进程问题

    如图2-4的程序流程图,在编写程序时,首先需要定义一些信号量,用来控制对共享资源缓冲区的使用权限,前面已经介绍,我定义了mutex、empty、full、proCmutex  4个信号量。初始化变量之后,开始创建生产者进程和消费者进程;生产者生产的产品存放到缓冲区,发送信号量通知消费,此时消费者收到信号量开始销售产品。销售完一个产品,就释放掉一个缓冲区的空间位置。

图2-4 进程流程图

第3章 实验结果

3.1 运行结果

    如图3-1、3-2所示,按照实验要求,在系统运行之前,打印出了我的个人信息,接着显示了生产的产品数量和当前的库存数量。按照实验要求,有4个工厂同时生产,有1个销售商进行销售,实验完成情况符合实验要求。

图3-1 运行初期界面

图3-2 运行中期界面

如图3-3、3-4所示,我设置的最大库存数量为100,当库存数量达到最大值时,打印:库存已满!并且停止生产,此时可以正常销售,当销售掉一个产品,此时库存数量小于100,这时又开始生产。并且实时打印了已销售的产品的数量。

图3-3 运行后期界面

图3-4 运行后期界面

3.2 结果分析

    结合题目要求和实验的运行结果可以看出,实验结果达到了实验要求。在我的实验中程序中,创建了两个任务,并定义了信号量来控制两个任务之间的进程问题,加上生产-消费的逻辑关系,经过大量的测试修改代码,最终较好的完成了实验。

第4章 实验总结

在本次实验中,我查阅基于μC/OS-II操作系统的生产者与消费者问题的大量资料。认识到μC/OS-II作为一款开源的嵌入式实时操作系统,为并发编程提供了强大的支持。生产者与消费者问题作为一个经典的并发问题,其核心在于多个任务(生产者、消费者)如何安全、高效地共享有限资源(缓冲区)。

我首先定义了生产者和消费者两个任务,并分配了相应的优先级和栈空间。生产者任务负责模拟数据的生成并放入缓冲区,而消费者任务则负责从缓冲区中取出数据进行处理。在任务实现过程中,我也考虑了数据的一致性和同步性,确保生产者和消费者之间的协调运作。

为了实现生产者与消费者之间的同步和互斥,我采用了μC/OS-II的信号量机制。通过创建信号量并对其进行合理的操作(如P操作和V操作),我成功地实现了对缓冲区的访问控制,避免了数据竞争和混乱。

在完成基本功能后,我进行了大量的测试工作。通过模拟不同的生产速度和消费速度,我验证了系统的稳定性和可靠性。同时,我还对代码进行了优化,提高了系统的运行效率和响应速度。

本次实验让我深刻体会到了μC/OS-II操作系统在并发编程中的强大功能和灵活性。通过实际编程操作,我不仅掌握了生产者与消费者问题的解决方案,还深入理解了任务同步与通信机制的重要性。同时,我也认识到了在编写并发程序时需要注意的问题,如数据一致性和同步性等。此外,本次实验还锻炼了我的编程能力和解决问题的能力,提高了我的实践能力和综合素质。

在未来的学习和工作中,我将继续深入学习μC/OS-II操作系统和其他实时操作系统的知识,并将其应用于更复杂的并发编程问题中,以提升自己的编程水平和解决问题的能力。同时,非常感谢顾老师的本学期的辛勤付出以及对我的教导。

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

用kimi一键绘制《庆余年》人物关系图谱

《庆余年》里面人物关系复杂&#xff0c;如果能画出一个人物关系图谱&#xff0c;可以直观的理解其中人物关系&#xff0c;更好的追剧。 首先&#xff0c;用kimi下载庆余年的分集剧情&#xff0c;常见文章《AI网络爬虫&#xff1a;批量爬取电视猫上面的《庆余年》分集剧情》&am…

【Java面试】三、Redis篇(下)

文章目录 1、抢券场景2、Redis分布式锁3、Redisson实现分布式锁4、Redisson实现的分布式锁是可重入锁5、Redisson实现分布式锁下的主从一致性6、面试 1、抢券场景 正常思路&#xff1a; 代码实现&#xff1a; 比如优惠券数量为1。正常情况下&#xff1a;用户A的请求过来&a…

Centos7.9上安装Oracle 11gR2 RAC 三节点(ASMlib管理asm磁盘)

服务器规划 OS 规格 主机名 IP VIP private IP scanip centos 7.9 1C4G racdb01 192.168.40.165 192.168.183.165 192.168.40.16 192.168.40.200 centos 7.9 1C4G racdb02 192.168.40.175 192.168.183.175 192.168.40.17 192.168.40.200 centos 7.9 1C4G…

目前流行的前端框架有哪些?

目前流行的前端框架有很多&#xff0c;它们可以帮助开发者快速构建高质量的前端应用程序。本文将介绍一些目前比较受欢迎的前端框架&#xff0c;并分析它们的优缺点。 React React 是一个由 Facebook 开发的开源前端JavaScript库&#xff0c;用于构建用户界面&#xff0c;尤其…

基于Vue的图片文件上传与压缩组件的设计与实现

摘要 随着前端技术的发展&#xff0c;系统开发的复杂度不断提升&#xff0c;传统开发方式将整个系统做成整块应用&#xff0c;导致修改和维护成本高昂。组件化开发作为一种解决方案&#xff0c;能够实现单独开发、单独维护&#xff0c;并能灵活组合组件&#xff0c;从而提升开…

OSPF多区域组网实验(华为)

思科设备参考&#xff1a;OSPF多区域组网实验&#xff08;思科&#xff09; 技术简介 OSPF多区域功能通过划分网络为多个逻辑区域来提高网络的可扩展性和管理性能。每个区域内部运行独立的SPF计算&#xff0c;而区域之间通过区域边界路由器进行路由信息交换。这种划分策略适用…

Python 机器学习 基础 之 数据表示与特征工程 【分类变量】的简单说明

Python 机器学习 基础 之 数据表示与特征工程 【分类变量】的简单说明 目录 Python 机器学习 基础 之 数据表示与特征工程 【分类变量】的简单说明 一、简单介绍 二、数据表示与特征工程 数据表示 特征工程 三、分类变量 1、One-Hot编码&#xff08;虚拟变量&#xff09…

【ArcGIS微课1000例】0112:沿线(面)按距离或百分比生成点

文章目录 一、沿线生成点工具介绍二、线状案例三、面状案例一、沿线生成点工具介绍 位置:工具箱→数据管理工具→采样→沿线生成点 摘要:沿线或面以固定间隔或百分比创建点要素。 用法:输入要素的属性将保留在输出要素类中。向输出要素类添加新字段 ORIG_FID,并设置为输…

Vue进阶之Vue项目实战(三)

Vue项目实战 图表渲染安装echarts图表渲染器(图表组件)图表举例:创建 ChartsRenderer.vue创建 ChartsDataTransformer.ts基于 zrender 开发可视化物料安装 zrender画一个矩形画一个柱状图基于svg开发可视化物料svg小示例使用d3进行图表渲染安装d3基本使用地图绘制本地持久化拓…

Leetcode861. 翻转矩阵后的得分

Every day a Leetcode 题目来源&#xff1a;861. 翻转矩阵后的得分 解法1&#xff1a;贪心 对于二进制数来说&#xff0c;我们只要保证最高位是1&#xff0c;就可以保证这个数是最大的&#xff0c;因为移动操作会使得它取反&#xff0c;因此我们进行行变化的时候只需要考虑首…

深度学习:手撕 RNN(2)-RNN 的常见模型架构

本文首次发表于知乎&#xff0c;欢迎关注作者。 上一篇文章我们介绍了一个基本的 RNN 模块。有了 这个 RNN 模块后&#xff0c;就像搭积木一样&#xff0c;以 RNN 为基本单元&#xff0c;根据不同的任务或者需求&#xff0c;可以构建不同的模型架构。本节介绍的所有结构&#…

Glassnode 内容主管:「减半」后的市场「抑郁」

原文标题&#xff1a;《Finance Bridge: Post-Halving Blues》撰文&#xff1a;Marcin Miłosierny&#xff0c;Glassnode 内容主管编译&#xff1a;Chris&#xff0c;Techub News 文章来源香港Web3媒体Techun News 摘要&#xff1a; 每月简报&#xff1a;4 月&#xff0c;尽…

前端自动将 HTTP 请求升级为 HTTPS 请求

前端将HTTP请求升级为HTTPS请求有两种方式&#xff1a; 一、index.html 中插入meta 直接在首页 index.html 的 head 中加入一条 meta 即可&#xff0c;如下所示&#xff1a; <meta http-equiv"Content-Security-Policy" content"upgrade-insecure-requests&…

从零开始傅里叶变换

从零开始傅里叶变换 1 Overview2 傅里叶级数2.1 基向量2.2 三角函数系表示 f ( t ) f(t) f(t)2.2.1 三角函数系的正交性2.2.2 三角函数系的系数 2.3 复指数函数系表示 f ( t ) f(t) f(t)2.3.1 复指数函数系的系数2.3.2 复指数函数系的正交性 2.4 傅里叶级数总结 3 傅里叶变换…

C++BuilderXE 如何让listView按文件名数字排序而非字母排序

int m_nDataColSort0; bool IsAsctrue; void __fastcall TForm1::RzListView4Compare(TObject *Sender, TListItem *Item1, TListItem *Item2, int Data, int &Compare) { if(m_nDataColSort0) { //按列表第二列排序 //CompareCompareText(Item1->SubItems-…

FreeRTOS学习——FreeRTOS队列(下)之队列创建

本篇文章记录我学习FreeRTOS队列创建的知识。主要分享队列创建需要使用的初始化函数、队列复位函数。 需要进一步了解FreeRTOS队列的相关知识&#xff0c;读者可以参考以下文章&#xff1a; FreeRTOS学习——FreeRTOS队列&#xff08;上&#xff09;_freertos 单元素队列-CSDN博…

第四节 Starter 加载时机和源码理解

tips&#xff1a;每个 springBoot 的版本不同&#xff0c;代码的实现存会存在不同。 上一章&#xff0c;我们聊到 mybatis-spring-boot-starter&#xff1b; 简单分析了它的结构。 这一章我们将着重分析 Starter 的加载机制&#xff0c;并结合源码进行分析理解。 一、加载实际…

基于魏格纳函数和焦散线方法的自加速光束matlab模拟与仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于魏格纳函数和焦散线方法的自加速光束matlab模拟与仿真。通过魏格纳函数法&#xff0c;来产生多种自加速的光束&#xff0c;设计自加速光束方法&#xff0c;模…

springBoot+springSecurity基本认证流程

springBootspringSecurity认证流程 整合springSecurity 对应springboot版本&#xff0c;直接加依赖&#xff0c;这样版本不会错 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId…

vue实战----网易云音乐案例

1 . 能够掌握Vant组件库使用2 . 熟练查阅Vant组件库文档3 . 能够完成网易云音乐案例 案例-网易云音乐 1.本地接口 目标&#xff1a;下载网易云音乐node接口项目, 在本地启动, 为我们vue项目提供数据支持 2.本地接口启动 目标&#xff1a;启动本地node服务_拿到数据 文档: …