操作系统课程设计报告多进程同步橘子苹果问题.docx

上传人:b****8 文档编号:9980233 上传时间:2023-02-07 格式:DOCX 页数:25 大小:253.92KB
下载 相关 举报
操作系统课程设计报告多进程同步橘子苹果问题.docx_第1页
第1页 / 共25页
操作系统课程设计报告多进程同步橘子苹果问题.docx_第2页
第2页 / 共25页
操作系统课程设计报告多进程同步橘子苹果问题.docx_第3页
第3页 / 共25页
操作系统课程设计报告多进程同步橘子苹果问题.docx_第4页
第4页 / 共25页
操作系统课程设计报告多进程同步橘子苹果问题.docx_第5页
第5页 / 共25页
点击查看更多>>
下载资源
资源描述

操作系统课程设计报告多进程同步橘子苹果问题.docx

《操作系统课程设计报告多进程同步橘子苹果问题.docx》由会员分享,可在线阅读,更多相关《操作系统课程设计报告多进程同步橘子苹果问题.docx(25页珍藏版)》请在冰豆网上搜索。

操作系统课程设计报告多进程同步橘子苹果问题.docx

操作系统课程设计报告多进程同步橘子苹果问题

操作系统课程设计报告

 

院(系):

计算机工程学院

专业:

计算机科学与技术专业

学生姓名:

__

班级:

__学号:

   

题目:

用多进程同步方法演示“桔子-苹果”问题____

起迄日期:

_2012.07.02_--2012.07.13_____

设计地点:

现代教育中心  

********

 

2011—2012年度第2学期

完成日期:

2012年7月13日

一、课程设计目的

本次实验进行操作系统课程设计的主要任务是模拟生产者和消费者的一个衍生,即实现“橘子-苹果问题”。

这个问题中有两个生产者,分别生产苹果核橘子,有两个消费者,分别消费橘子和苹果。

同时,因为两个生产者和两个消费者对同一个缓冲区进行操作,所以应互斥的访问缓冲区以保证程序的正确性。

本次实验的目的就是加深各个进程正确有效的对资源的访问,即同步和互斥。

同时掌握信号量在互斥访问中的使用。

掌握生产者和消费者问题的流程和实现方法。

同时提高编程的能力、对问题的解决能力及查阅文档的能力。

二、课程设计内容与要求

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

2、说明:

有两类生产者,一类负责生产桔子,一类负责生产苹果;有两类消费者,一类负责消费桔子,一类负责消费苹果;他们共享一个有20个存储单元的有界缓冲区,每个存储单元只能放入一种产品(桔子/苹果)。

3、设计要求:

1)二类生产者与二类消费者数目均为20,即20个生产者负责生产桔子,20个生产者负责生产苹果;20个消费者负责消费桔子,20个消费者负责消费苹果

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

3)多个生产者或多个消费者之间必须有共享对缓冲区进行操作的函数代码,同时需要考虑算法的效率性

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

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

三、系统分析与设计

1、系统分析

1.此次任务是实现特殊生产者和消费者的演示程序,所需要处理的信息是生产者和消费者的个数,生产苹果、橘子和消费苹果、橘子的速度控制,缓冲区中橘子和苹果的个数和当前生产、消费指针的位置。

2.程序中需要处理缓冲区的动态显示、生产者和消费者的速度可以调节,生产者和消费者个数可以改变。

为了实现界面的友好性,应该对用户标明清楚各个模块的作用。

同时实时的对程序进行暂停和停止。

演示程序中用图形显示的方法描述缓冲区的使用情况,即当前缓冲区有多少个苹果和橘子,还有生产和消费者的指针。

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

可以调节橘子和苹果的生产速度和消费苹果和橘子的速度,在文本框中输入相应的速度,再按下修改按键即可实现速度的实时调节。

在苹果生产者、橘子生产者、苹果消费者、橘子消费者中实现对个数按钮的按下即可动态实时的调节生产者和消费者的个数的调节。

在界面的最下面点击开始按钮,程序开始运行,暂停按钮使程序暂停挂起,再点击则可以继续运行。

停止按钮实现此次程序的演示结束。

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

5.系统界面如下:

2、系统设计:

2.1、模块设计:

2.2、数据结构说明:

1.缓冲区的数据结构:

双端队列

说明:

左端放置生产苹果的指针,右端放置生产橘子的指针。

2.缓冲区操作的类图,实现对缓冲区的实际操作

2.3、算法流程图:

1.生产苹果算法

2.消费苹果算法

3.绘图算法

4.生产苹果者人工智能算法(生产橘子人工智能相似)

5.苹果消费者人工智能算法(生产橘子算法类似)

四、系统测试与调试分析

1、系统测试

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

测试说明

测试名称

用多进程同步方法演示“桔子-苹果”问题

测试目的

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

测试技术

单元测试

测试方法

黑盒测试法

测试用例

测试内容

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

测试步骤

增加苹果生产者

等待缓冲区被用完

增加苹果消费者

测试数据

增加苹果生产者到3

缓冲区苹果数量20

缓冲区空闲位为0

苹果消费者增加到4

预期结果

缓冲区开始增加苹果

缓冲区满苹果生产者阻塞

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

测试结果

与预期相符

与预期相符

与预期相符

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

唤醒的实现是否正常。

测试说明

测试名称

用多进程同步方法演示“桔子-苹果”问题

测试目的

验证多个苹果橘子生产者和苹果、橘子消费者互斥操作缓冲区

测试技术

单元测试

测试方法

黑盒测试法

测试用例

测试内容

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

测试步骤

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

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

开始增加生产者

减少消费者

测试数据

橘子生产者数量5

苹果生产者数量5

苹果生产者减少到0

橘子生产者减少到0

增加橘子消费者到5

增加苹果消费者到5

增加苹果生产者到5

增加橘子生产者到5

减少橘子消费者到2

减少苹果消费者到2

预期结果

缓冲区内产品数量每次减少10个

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

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

测试结果

与预期相符

与预期相符

与预期相符

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

测试说明

测试名称

用多进程同步方法演示“桔子-苹果”问题

测试目的

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

测试技术

单元测试

测试方法

黑盒测试法

测试用例

测试内容

调节生产者和消费者速度

测试步骤

开始程序运行

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

点击修改按钮

测试数据

苹果、橘子生产者速度

2000

苹果、橘子消费者速度

2000

生产者的速度值1000

消费者速度值1000

点击修改

预期结果

缓冲区开始被操作

界面文本框中显示速度值

生产者、消费者速度变化到1000

测试结果

与预期相符

与预期相符

与预期相符

(4)实现了人工智能操作:

即系统自动保持生产者和消费者的相对平衡,测试功能的正确实现

测试说明

测试名称

用多进程同步方法演示“桔子-苹果”问题

测试目的

测试编写的人工智能是否实现

测试技术

单元测试

测试方法

黑盒测试法

测试用例

测试内容

自动维持缓冲区的稳定

测试步骤

开始程序的运行

运行人工智能操作

测试数据

苹果生产者5

苹果消费者5

橘子生产者3

橘子消费者0

减少苹果生产者到0

增加苹果消费者数量到6

预期结果

缓冲区开始被操作

生产者、消费者数量都靠拢至4

测试结果

与预期相符

与预期相符

与预期相符

 

2、调试分析:

(1)程序编写过程中,因为有两个生产者和消费者,极易把操作写错。

在编写增加苹果数量额函数中,程序中午无法增加苹果数量。

解决办法:

在函数中查找错误,对苹果的操作写成了对橘子的操作,导致程序出现问题。

(2)在对缓冲区进行绘图的时候,java的JComponent组件内绘图位置出现错误。

解决办法:

JComponent内绘图时因为JComponent内使用的是相对坐标,所以不能使用面板的绝对坐标,换成相对坐标正确绘图。

(3)实现人工智能操作的时候,点击相应按钮无法执行

解决办法:

在排查完毕后,发现按键响应没有对程序已经设计的标志值进行修改,致使程序没有按预期执行,修改完标志值即可以。

五、用户手册

1.使用的语言和平台

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

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

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

3.程序使用步骤

图1:

系统登录界面。

图2:

生产者速度调节图3:

消费者速度调节

图4:

生产者数量调节图5:

消费者数量调节

图6:

控制界面

图7:

动态可视化缓冲区

4.程序使用步骤:

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

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

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

4)在程序运行状态,可以点击“人工智能”按钮,可以实现人工智能自动操作缓冲区,保持缓冲区的产品数量和种类的稳定,不至于产品数量过多或过少,也不会出现某种产品数量过多或者过少。

六、程序清单

publicvoidincreaseapple()

{

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

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

if(pointapple+1!

=pointorange){

pointapple++;

if(pointapple==20)

pointapple=19;

isFull[pointapple]=true;//将生产了产品的标志位设置为满applenum++;

storage[pointapple]='A';//存储生产的产品

pool[pointapple]=1;//标志此位置生产的是苹果,1表示苹果

}

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

Apple.textArea2.append("生产者生产了一个苹果"+str2+"运行\n");

number++;

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

Apple.textArea1.append("它们是:

\n");

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

{

if(storage[j]!

='0')

Apple.textArea1.append("("+j+")"+storage[j]+"");

else

Apple.textArea1.append("");

}

Apple.textArea1.append("\n");

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

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

apple.release();//增加苹果信号量的值

}

publicvoidincreaseorange()

{

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

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

if(pointapple+1!

=pointorange){

pointorange--;

if(pointorange<0)

pointorange=0;

isFull[pointorange]=true;//将此位置设置成满状态

orangenum++;

storage[pointorange]='O';//存储生产产品,O表示橘子

pool[pointorange]=2;//标志此位置是橘子,2表示橘子

}

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

Apple.textArea2.append("生产者生产了一个橘子"+str2+"运行\n");

number++;

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

Apple.textArea1.append("它们是:

\n");

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

{

if(storage[j]!

='0')

Apple.textArea1.append("("+j+")"+storage[j]+"");

else

Apple.textArea1.append("");

}

Apple.textArea1.append("\n");

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

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

orange.release();//增加橘子信号量的值

}

publicvoiddecreaseapple()

{

apple.acquire();//申请获得苹果

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

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

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

Apple.textArea2.append("消费者"+str2+"运行\n");

number--;

applenum--;

isFull[pointapple]=false;//此位置设置为空

pool[pointapple]=0;//标志此位置是空位置,0表示空

Apple.textArea2.append("苹果消费一个"+storage[applepool[applenum]]+"运行\n");

storage[pointapple]='0';

pointapple--;//苹果指针减1

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

Apple.textArea1.append("它们是:

\n");

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

{

if(storage[j]!

='0')

Apple.textArea1.append("("+j+")"+storage[j]+"");

else

Apple.textArea1.append("");

}

Apple.textArea1.append("\n");

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

empty.release();//空缓冲区信号量+1

}

publicvoiddecreaseorange()

{

orange.acquire();//申请获得橘子

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

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

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

Apple.textArea2.append("消费者"+str2+"运行\n");

number--;

orangenum--;

isFull[pointorange]=false;

pool[pointorange]=0;

Apple.textArea2.append("橘子消费一个"+storage[orangepool[orangenum]]+"运行\n");

storage[pointorange]='0';

pointorange++;//橘子指针右移一位

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

Apple.textArea1.append("它们是:

\n");

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

{

if(storage[j]!

='0')

Apple.textArea1.append("("+j+")"+storage[j]+"");

else

Apple.textArea1.append("");

}

Apple.textArea1.append("\n");

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

empty.release();//空信号量+1

}

classSemaphore{

intvalue;

publicSemaphore(intv){

this.value=v;

}

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

publicsynchronizedvoidacquire(){

value--;

if(value<0){

try{

this.wait();

}catch(InterruptedExceptione){

e.printStackTrace();

}

}

}

publicsynchronizedvoidrelease(){

value++;

if(value<=0){

this.notify();

}

}

}

}

publicstaticintincreaseappleProducer()//增加苹果生产者线程

{

if(i1<20)

{

appleincrease[i1]=newIncreaseapple(myStorage);

appleincrease[i1].start();

i1++;

}

returni1;

}

publicstaticintincreaseorangeProducer()//增加橘子生产者线程

{

if(i2<20)

{

orangeincrease[i2]=newIncreaseorange(myStorage);

orangeincrease[i2].start();

i2++;

}

returni2;

}

publicstaticintdecreaseappleProducer()//减少苹果生产者线程

{

if(i1>0)

{

appleincrease[i1-1].out=true;

appleincrease[i1-1]=null;

i1--;

}

returni1;

}

publicstaticintdecreaseorangeProducer()//减少橘子生产者线程

{

if(i2>0)

{

orangeincrease[i2-1].out=true;

orangeincrease[i2-1]=null;

i2--;

}

returni2;

}

 

publicstaticintincreaseappleConsumer()//增加苹果消费者线程

{

if(d1<20)

{

appledecrease[d1]=newDecreaseapple(myStorage);

appledecrease[d1].start();

d1++;

}

returnd1;

}

publicstaticintincreaseorangeConsumer()//增加橘子消费者线程

{

if(d2<20)

{

orangedecrease[d2]=newDecreaseorange(myStorage);

orangedecrease[d2].start();

d2++;

}

returnd2;

}

publicstaticintdecreaseappleConsumer()//减少苹果消费者线程

{

if(d1>0)

{

appledecrease[d1-1].out=true;

appledecrease[d1-1]=null;

d1--;

}

returnd1;

}

publicstaticintdecreaseorangeConsumer()//减少橘子消费者线程

{

if(d2>0)

{

orangedecrease[d2-1].out=true;

orangedecrease[d2-1]=null;

d2--;

}

returnd2;

}

七、体会与自我评价

对于此次课程设计,我使用的是做图形用户界面比较容易的java语言,但是自己对java的掌握也不是很深入,尤其是这门不断发展壮大的语言,里面包含了各方面的操作,所以掌握起来难度不小,此次课设基本上都是在开学后的这两周内完成的。

这次实验中需要用到的操作种类很多很杂乱,我都是先在纸上设计完完毕,之后再一点点的将它在计算机中实现预期的效果,在一点点的设计中,每当攻克了一个自己认为难的地方的时候,就会有一种喜悦感产生,促使我去解决更多的问题,这就是学习的乐趣吧,只是单纯的将自己的任务完善,追求更高的要求。

后来自己做程序做上瘾了,不断有新奇的想法蹦出来,我就开始痴迷的设计实现,结果到现在程序的质量已经远远超过了我的预期。

我自此明白了学习追求上的快乐。

此次课程设计在实现缓冲区动态图形显示的时候自己遇到了困境,在查阅了多方资料后仍然没有什么进展,自己开始着急,担心会做不完,不过依旧每天呆在电脑前,不断的积累经验,最后才找到绘图的方法,成果的在界面中描绘出了自己想要的图形。

自己一直都想去追求更高的分数,做的尽善尽美,力图超额完成老师的任务,不断的添加自己想到的新功能。

但最后完成课程设计的时候,我终于明白,分数不过是个数字,知识才是自己的。

通过这次课程设计,我确实学到了很多东西,多年后我可能已经忘记这次课设最后打了多少分,但这些学到的东西却可以使我受益终生。

除了知识技术上的东西,我更锻炼了自己的快速学习能力;我学会了如何快速有效地从图书馆、网络获取自己需要的信息;我尝到了在周围很多同学拷来拷去时孤军奋战的痛苦;我体会了夜以继日完成一个项目时中途过程的艰辛及最终完成后巨大的成就感……我更加深了人生的信心,以后面对任何一个困难的项目,我想我都不会惧怕,并最终能够成功地将其完成。

   感谢老师,感谢此次课程设计。

虽然在

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

当前位置:首页 > 农林牧渔 > 林学

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

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