【操作系统实验】生产者消费者实验

一、实验目的

通过本实验,加深对进程概念的理解,明确进程与程序的区别;认识并发执行的本质,理解和掌握Linux和Windows进程通信系统调用的功能,通过实验和学习,提高对进程痛惜系统调用的编程能力;掌握使用信号量机制完成进程间同步和互斥的方法。

二、实验内容

在Windows操作系统下创建一个有6个缓冲区的缓冲池,初始为空,每个缓冲区能存放一个长度为10个字符的字符串,同时创建2个生产者和3个消费者,用进程模拟生产者或消费者。

对于生产者而言,随机等待一段时间后,往缓冲区中存数据,若缓冲区满,则等待消费者取走数据后再存放,每个生产者存12次数据。

对于消费者而言,随机等待一段时间后,从缓冲区中取数据,若缓冲区空,则等待生产者存放数据后再取走,每个消费者取8次数据。

显示每次向缓冲区添加或取走的数据以及时间,每次操作后都要显示缓冲区中的全部数据,生产者、消费者进程号。

三、程序设计与实现

1.实验环境

虚拟机:CentOS 7

操作系统:Windows10

开发环境:RedPanda-Cpp.0.14.2.64位.10.3

2.设计思路

① 定义共享内存区

struct BUF {

char array[BufAmount][BufLen];

int head;

int tail;

int IsEmpty;

};

共享内存区中的array表示生产者和消费者存取数据的环形缓冲区,设置其大小BufAmount为6,其单条数据长度BufLen为10。指针head用于指向消费者下一次待取的数据,指针tail指向生产者下一次需要存放数据的缓冲,IsEmpty用来表示环形缓冲区是否为空,取0为不空,取1为空。

② 设置信号量

在实验中,设置三个信号量如下:

互斥信号量MUTEX:用于生产者进程与生产者进程、消费者进程与生产者进程、消费者进程与消费者进程间互斥使用缓冲区,初始值为1。

同步信号量EMPTY:用于指示当前空缓冲区的可用数量,用于制约生产者进程向缓冲区存数据,初始值为6。

同步信号量FULL:用于指示当前有数据的缓冲区的数量,用于制约消费者进程取数据,初始值为0。

③ 生产者存数据

(1) GetRandomChar()和GetRandomNum():随机产生不定长字符串作为数据。

(2) Sleep(GetRandomSleep()):随机进行等待。

(2) P(EMPTY):申请一个空缓冲单元,EMPTY-1。

(4) P(MUTEX):申请环形缓冲区的唯一使用权,MUTEX-1。

(5) strcpy(pbuf->array[pbuf->tail],charray):生产者进程向缓冲区中存放数据。

(6) pbuf->tail=(pbuf->tail+1)%BufAmount:修改尾指针,指向下一个缓冲单元。

(7) pbuf->IsEmpty=1:修改缓冲区状态IsEmpty。

(8) V(MUTEX):生产者进程释放对环形缓冲区的使用权,MUTEX+1

(9) V(FULL):FULL+1,表示环形缓冲区中可取数据的总量,唤醒消费者进程

④ 消费者取数据

(1) Sleep(GetRandomSleep()):随机进行等待。

(2) P(FULL):申请一个放有数据的缓冲单元,FULL-1。

(3) P(MUTEX):申请环形缓冲区的唯一使用权,MUTEX-1。

(4) strcpy(charray,pbuf->array[pbuf->head]):取得当前头指针指向的数据,(5) memset(pbuf->array[pbuf->head,‘\0’, sizeof(pbuf->array[pbuf-> head])) :清除存储这一数据的缓冲单元的内容。

(6) pbuf->IsEmpty=(pbuf->head==pbuf->tail):修改缓冲区状态.

(7) pbuf->head=(pbuf->head+1)%BufAmount:修改指针指向下一缓冲单元。

(8) V(MUTEX):消费者进程释放对环形缓冲区的使用权.

(9) V(EMPTY):Empty+1,表示环形缓冲区中空缓冲单元的数量,用于唤醒生

产者进程向缓冲区中存数据。

在生产与消费的过程中,有同步信号量FULL和EMPTY控制消费者或生产者是否能够申请缓冲单元,避免出现缓冲区满而生产者仍然往里放数据,缓冲区空而消费者仍然在取数据的情况。

此外,由于MUTEX的存在,保证各进程能够互斥使用环形缓冲区,MUTEX、FULL与EMPTY的合理搭配保证不会有死锁的产生。

3. 编写、编译代码

在开发环境中编写C++代码,调用相关接口实现相应功能。

4.运行得到结果

四、实验结果及分析

操作过程中,通过进程模拟2个生产者,编号分别为16864、10052,3个消费者,编号为21408、19796、21068。

从2022年10月5日11时43分19秒到11时43分37秒,父进程共完成24次存数据和24次取数据过程,环形缓冲区由空到满再次到空,实现字符串数据的存取,“生产者消费者问题”得到解决。

实验结果如下图。

五、实验收获与体会

“生产者消费者问题”是信号量知识里非常经典的案例,通过本次实验,我进一步加深了对进程概念的理解,深刻认识到并发执行的本质。

在Windows操作系统里,我利用信号量机制用进程模拟生产者和消费者,完成了进程间的同步和互斥。在看到正确运行结果的那一刻,我觉得编写与修改代码所付出的一切辛苦都是值得的。

在亲自动手实验的过程中,我对信号量知识点有了更深刻的理解,同时也复习了程序设计方面的知识,真可谓“一举两得”,这次实验让我收获颇多!

源码及实验报告:https://github.com/YourHealer/OS-Producer-and-Consumer.git

  • 4
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ayaishere_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值