多进程同步方法演示生产者消费者问题.docx

上传人:b****7 文档编号:9453588 上传时间:2023-02-04 格式:DOCX 页数:19 大小:144.58KB
下载 相关 举报
多进程同步方法演示生产者消费者问题.docx_第1页
第1页 / 共19页
多进程同步方法演示生产者消费者问题.docx_第2页
第2页 / 共19页
多进程同步方法演示生产者消费者问题.docx_第3页
第3页 / 共19页
多进程同步方法演示生产者消费者问题.docx_第4页
第4页 / 共19页
多进程同步方法演示生产者消费者问题.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

多进程同步方法演示生产者消费者问题.docx

《多进程同步方法演示生产者消费者问题.docx》由会员分享,可在线阅读,更多相关《多进程同步方法演示生产者消费者问题.docx(19页珍藏版)》请在冰豆网上搜索。

多进程同步方法演示生产者消费者问题.docx

多进程同步方法演示生产者消费者问题

青岛理工大学

操作系统课程设计报告

 

院(系):

计算机工程学院

专业:

计算机科学与技术专业

学生姓名:

__

班级:

_______ 学号:

   

题目:

用多进程同步方法演示“生产者-消费者”问题

起迄日期:

  

设计地点:

指导教师:

 

年度第学期

完成日期:

年月日

一、课程设计目的

本次进行操作系统课程设计的主要任务是设计一个模拟生产者消费者工作的系统。

这个问题中有一种生产者和一种消费者,生产者和消费者对同一个缓冲区进行操作,互斥的访问缓冲区。

本次课程设计的目的就是加深对多进程如何正确访问资源的认识,同时掌握信号量在互斥访问时应该如何正确有效地使用。

掌握生产者消费者问题的解决流程和方法,提高编程能力、解决问题的能力和查阅文档的能力。

二、课程设计内容与要求

1、设计目的:

通过研究Linux的进程同步机制和信号量,实现生产者消费者问题的并发控制。

2、说明:

有界缓冲区内设有20个存储单元,放入取出的产品设定为20个100以内的随机整数。

3、设计要求:

1)生产者与消费者均有二个以上

2)生产者和消费者进程的数目在程序界面上可调,在运行时可随时单个增加与减少生产者与消费者

3)生产者的生产速度与消费者的消费速度均可在程序界面调节,在运行中,该值调整后立即生效

4)生产者生产的产品由随机函数决定

5)多个生产者或多个消费者之间必须有共享对缓冲区进行操作的函数代码

6)每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的全部内容、当前生产者与消费者的指针位置,以及生产者和消费者线程标识符

7)采用可视化界面,可在运行过程中随时暂停,查看当前生产者、消费者以及有界缓冲区的状态

三、系统分析与设计

1、系统分析

系统分析

1.此次课程设计的任务是生产者消费者问题的模拟演示,需要处理的数据有:

生产者进程数目,消费者进程数目,生产者生产速度,消费者消费速度,缓冲区中产品的个数,以及生产、消费产品的指针。

2.程序中需要缓冲区中的信息可以动态演示,生产者、消费者的个数以及生产、消费时的速度可以随时调节,同时为了使程序更加友好,应该具有开始、暂停、停止等相关可操作按钮。

3.系统对外的界面如下:

1)对进程个数的修改:

点击生产者、消费者进程数据文本框下的增加、减少按钮

2)对速度的修改:

速度值默认为2000ms/个,如需修改,则在速度文本框中输入所修改的值,点击修改按钮即可进行修改。

3)需要开始模拟时,点击右上方的开始按钮。

如需暂停模拟过程,可点击暂停按钮。

当需要运行完毕时,点击停止按钮,进程工作停止。

4.此次使用java平台实现,保证了程序在各种机器的运行,只需要事前建立java的运行环境即可,便于程序的移植

5.系统界面如下:

 

2、系统设计:

2.1、模块设计:

 

2.2、数据结构说明:

 

2.3、算法流程图:

生产者流程图:

 

消费者流程图:

 

四、系统测试与调试分析

1、系统测试

(1)因为当生产者在缓冲区满了以后自动阻塞,需要消费者唤醒,所以需要测试唤醒的实现是否正常。

测试说明

测试名称

用多进程同步方法演示“生产者-消费者”问题

测试目的

验证生产者能被消费者唤醒

测试技术

单元测试

测试方法

黑盒测试法

测试用例

测试内容

当生产者生产满缓冲区后,开始增加消费者,唤醒生产者

测试步骤

增加生产者

等待缓冲区被用完

增加消费者

测试数据

增加生产者到2

缓冲区产品数量20

缓冲区空闲位为0

苹果消费者增加到3

预期结果

缓冲区开始增加产品

缓冲区满生产者阻塞

生产者被唤醒,缓冲区中产品数量减少

测试结果

与预期相符

与预期相符

与预期相符

(2)因为当生产者在缓冲区满了以后自动阻塞,需要消费者唤醒,所以需要测试

唤醒的实现是否正常。

测试说明

测试名称

用多进程同步方法演示“生产者-消费者”问题

测试目的

验证多个生产者和消费者互斥操作缓冲区

测试技术

单元测试

测试方法

黑盒测试法

测试用例

测试内容

缓冲区为空,消费者阻塞时,生产者唤醒消费者

测试步骤

开始生产产品,缓冲区为空空闲位20

开始消费产品,终止生产线程

开始增加生产者

减少消费者

测试数据

生产者数量5

生产者减少到0

增加消费者到5

增加生产者到5

减少消费者到2

预期结果

缓冲区内产品数量每次增加5个

消费完成产品,消费者阻塞

唤醒消费者,缓冲区中产品增加

测试结果

与预期相符

与预期相符

与预期相符

3)测试生产者和消费者的速度是否可以调节

测试说明

测试名称

用多进程同步方法演示“生产者-消费者”问题

测试目的

苹果、橘子生产者和苹果、橘子消费者速度可以调节

测试技术

单元测试

测试方法

黑盒测试法

测试用例

测试内容

调节生产者和消费者速度

测试步骤

开始程序运行

输入生产者、消费者速度值

点击修改按钮

测试数据

生产者速度2000

消费者速度2000

生产者速度值1000

消费者速度值1000

点击修改

预期结果

缓冲区开始被操作

界面文本框中显示速度值

速度均变化到1000

测试结果

与预期相符

与预期相符

与预期相符

 

2、调试分析:

1.在编写过程中,由于函数较多,开始时由于名称不够清晰,程序出现错误。

2.测试运行过程中,由于函数名称的相似,出现引用混乱的情况,程序无法正常运行。

3.在制作界面时,由于遗忘了chuangkou.add(jp);chuangkou.setVisible(true);两个语句,导致界面无法正常显示。

4.制作界面时,对各个控件的坐标和大小考虑不周,导致界面混乱,影响美观。

五、用户手册

1.使用的语言和平台

本次实验使用的是java语言的eclipse平台

2.对于程序运行环境的注意事项

需要安装java运行环境,eclipss平台不需要安装,只需要下载完成就可以使用。

3.程序使用步骤

图1:

系统登录界面。

图2:

生产者速度调节图3:

消费者速度调节

图4:

生产者数量调节图5:

消费者数量调节

图6:

控制界面

图7:

动态显示缓冲区

4.程序使用步骤:

1)单击开始按钮,程序开始初始化执行

2)点击增加按钮分别增加生产者和消费者,可以看到可视化缓冲区开始运动

3)在速度调节部分调节生产者和消费者的速度,可以看到缓冲区出现预期的产品种类和数量的变化。

六、程序清单

classConsumerextendsThread

{

privatehuanchongquhcq;//保存一个缓冲区类的引用

staticlongspeed=2000;//speed表示消费者线程的速度

staticintcpause=0;//cpause变量用来控制消费者线程的开始与暂停

booleanout=false;

//定义构造方法,接收一个缓冲区类型的变量

publicConsumer(huanchongquhcq)

{

this.hcq=hcq;

}

//run()方法调用接收的缓冲区类型的变量指向的decrease()方法,开始消费元素。

@Override

publicvoidrun()

{

while(!

out)

{

if(out)

break;

if(cpause==1)

{

try

{

Thread.sleep(speed);

}

catch(InterruptedExceptione)

{

e.printStackTrace();

}

hcq.Consume();

}

}

}

}

classProducerextendsThread

{

privatehuanchongquhcq;//定义缓冲区类的引用。

staticlongspeed=2000;//定义speed变量,表示线程速度

booleanout=false;

publicstaticintppause=0;//ppause变量用来控制生产者线程的开始与暂停

 

//定义构造方法,接收一个缓冲区类型的变量

publicProducer(huanchongquhcq)

{

this.hcq=hcq;

}

publicvoidchangeout()

{

out=!

out;

}

//run()方法调用缓冲区类型变量指向的对象的increase()方法,开始生产元素。

@Override

publicvoidrun()

{

while(!

out)

{

if(out)

break;

if(ppause==1)

{

try

{

Thread.sleep(speed);

}

catch(InterruptedExceptione)

{

e.printStackTrace();

}

hcq.Produce();

}

}

}

}

classhuanchongqu

{

//number表示动态缓冲区中元素的数量

staticintnumber=0;

staticboolean[]E_F=newboolean[20];//缓冲区状态控制

staticint[]storage=newint[20];

staticSemaphoreempty=newSemaphore(20);

staticSemaphorefull=newSemaphore(0);

staticSemaphorechanpin=newSemaphore(0);

staticSemaphoremutex=newSemaphore

(1);

staticintcpnum=0;

staticintpointcp=-1;

publichuanchongqu()

{

for(inti=0;i<20;i++)

{

E_F[i]=false;

storage[i]='0';

}

}

publicvoidProduce()

{

empty.acquire();//信号量的p操作,申请空缓冲区

mutex.acquire();//互斥信号量

if(pointcp+1!

=20){

pointcp++;

E_F[pointcp]=true;//将生产了产品的标志位设为满

cpnum++;

storage[pointcp]=(int)(Math.random()*99+0);//存储生产的产品

}

Stringstr2=Thread.currentThread().getName();

pc.ta2.append("生产者"+str2+"运行\n");

number++;

pc.ta1.append("仓库中的产品个数为"+number+"\n");

pc.ta1.append("它们是:

\n");

for(intj=0;j<20;j++)

{

if(storage[j]!

='0')

pc.ta1.append("("+j+")"+storage[j]+"");

else

pc.ta1.append("");

}

if(number==20){

pc.ta1.append("\n仓库已满");

}

pc.ta1.append("\n");

mutex.release();//释放互斥锁

full.release();//增加满信号量的值

chanpin.release();//增加产品信号量的值

}

publicvoidConsume()

{

chanpin.acquire();//申请获得产品

full.acquire();//申请满缓冲区

mutex.acquire();//互斥进入临界区

Stringstr2=Thread.currentThread().getName();

pc.ta2.append("消费者"+str2+"运行\n");

number--;

cpnum--;

E_F[pointcp]=false;//设置为空

storage[pointcp]='0';

pointcp--;//产品指针减一

pc.ta1.append("仓库中的数字个数为"+number+"\n");

pc.ta1.append("它们是:

\n");

for(intj=0;j<20;j++)

{

if(storage[j]!

='0')

pc.ta1.append("("+j+")"+storage[j]+"");

else

pc.ta1.append("");

}

if(number==0){

pc.ta1.append("\n仓库已空");

}

pc.ta1.append("\n");

mutex.release();//退出临界区

empty.release();//空缓冲区信号量加一

}

}

classSemaphore{

intvalue;

publicSemaphore(intv){

this.value=v;

}

//定义P、V原语操作,原语操作就是执行时不能中断,所以synchronized修饰

publicsynchronizedvoidacquire(){//获取

value--;

if(value<0){

try{

this.wait();//等待

}catch(InterruptedExceptione){

e.printStackTrace();

}

}

}

publicsynchronizedvoidrelease(){//释放

value++;

if(value<=0){

this.notify();//唤醒

}

}

}

七、体会与自我评价

对于本次课程设计,我采用了java语言进行程序编制。

因为相对于mfc等,java语言更轻便简洁,在绘制可视化图形界面时也相对容易很多。

可是由于对java了解不深,掌握的也不是很好,所以编制的程序并不算完美。

比如在按了暂停按钮或停止按钮之后,程序会出现延迟等现象。

本次实验并没有特别困难的算法。

其实主要的算法只有两种,一种是生产者的生产过程,一种是消费者的消费过程。

在设计过程中,由于生产者与消费者需要互斥的访问缓冲区,将产品放进去或从里面取出,所以最后决定使用指针的方法,通过指针前后移动来表现产品被放入缓冲池或取出缓冲池的过程。

刚开始时,我将指针的初值设置为0,但是出现的产品只有19个,不符合20个缓冲池的要求。

后来我发现是我对指针存在理解错误并将初值设置改为-1之后,运行程序时生产的终于是从编号0开始、一共20个产品了。

同时,按照要求,生产者生产的产品必须是20个100以内的随机数,所以我使用了Math.random()随机函数来实现这个功能要求。

控制生产者消费者工作的主要是信号量。

根据课本上的介绍,我选择了empty、full和mutex信号量,然后根据书上用记录型信号量实现生产者消费者的算法,编制程序以实现相关的功能。

通过查找一些资料,最后决定使用synchronized来修饰获得和释放的过程,从而使获取和释放过程可以连贯起来。

在绘制界面时遇到了很多麻烦。

比如遗忘了某些语句导致界面不能显示,或是坐标和大小设置的不合理影响了整个界面的布局,使界面不够美观友好等。

在多次尝试和修改,终于将界面上各种控件安排到了比较理想的位置。

但是在我想为界面插入背景图片时,屡次尝试均没有获得成功,最后由于时间的限制所以放弃了。

本次课程设计让我对生产者消费者问题的处理有了更深一层的认识和掌握,同时也对java语言的运用有了更多的理解,相信这对我未来的学习会很有帮助。

八、参考文献

[1]汤子瀛编著,计算机操作系统(修订版),西安电子科技大学出版社,2001年

[2]张晓龙主编,Java程序设计与开发,电子工业出版社,2010年

[3]胡明庆,高巍,钟梅操作系统教程与实验清华大学出版社2007年

[4]李善平操作系统学习指导和考试指导浙江大学出版社2004年

[5]汤小丹梁红兵计算机操作系统学习指导与题解西安电子科技大学2008年

九、课程设计评价(由任课教师填写)

课程设计评价

 

成绩:

教师:

年月日

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 党团工作 > 入党转正申请

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1