生产者与消费者算法实现.docx

上传人:b****6 文档编号:4763379 上传时间:2022-12-08 格式:DOCX 页数:14 大小:58.83KB
下载 相关 举报
生产者与消费者算法实现.docx_第1页
第1页 / 共14页
生产者与消费者算法实现.docx_第2页
第2页 / 共14页
生产者与消费者算法实现.docx_第3页
第3页 / 共14页
生产者与消费者算法实现.docx_第4页
第4页 / 共14页
生产者与消费者算法实现.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

生产者与消费者算法实现.docx

《生产者与消费者算法实现.docx》由会员分享,可在线阅读,更多相关《生产者与消费者算法实现.docx(14页珍藏版)》请在冰豆网上搜索。

生产者与消费者算法实现.docx

生产者与消费者算法实现

 

课程设计说明书

 

题目:

生产者与消费者算法模拟

 

院系:

计算机科学与工程

专业班级:

信息安全(xxxx)班

学号:

201130xxxx

学生姓名:

xxxx

指导教师:

xxxx

2013年xx月xx日

 

xxxx大学课程设计(论文)任务书

计算机院系计算机教研室

学号

20113xxxxx

学生姓名

xxxx

专业(班级)

xxxxx

设计题目

生产者与消费者算法模拟

(1)系统作业或进程的数目;

(2)系统资源的种类和数目;

(3)系统作业或进程的对每类资源的最大需求数目;

(4)系统作业或进程已分配的资源数目。

(1)检查系统安全状态:

根据系统作业或进程的对每类资源的最大需求数目、已分配的资源数目等计算是否存在安全序列。

(2)检查系统是否可以继续某个进程资源分配请求。

要求设计说明书的字数在3000字以上。

2012.11.25-11.26根据课程设计的要求,查找相关资料,完成需求分析;

2012.11.26-11.27进行系统的概要设计;

2012.11.27-11.28进行系统的详细设计和源代码的书写;

2013.11.29-11.30对系统进行调试分析,写出课程设计报告。

[1]CayS.Horstmann,GaryCornell编著.JAVA核心技术卷I.北京:

机械工业出版社,2008.

[2]郑莉编著.Java语言程序设计(第二版).北京:

清华大学出版社,2011.

[3]吕国英等编著.算法设计与分析.北京:

清华大学出版社,2009.

[4]马小军等编.软件工程项目案例与实践指导.北京:

清华大学出版社,2013.

[5]汤子瀛等编著.计算机操作系统.西安:

西安电子科技大学出版社,2011.

指导教师签字

教研室主任签字

2012年xx月xx日

指导教师评语:

 

成绩:

指导教师:

年月日

xxxx大学课程设计(论文)成绩评定表

 

1.问题描述

1.1目的

掌握信号的使用方法和P、V操作的定义,掌握使用P、V操作实现进程之间同步与互斥的方法,加深对进程同步互斥概念的理解。

1.2设计要求

设计一程序,由一个进程创建三个子进程,三个子进程一个是生产者进程,两个是消费者进程,且要求:

●父子进程都使用父进程创建的共享存储区进行通信,由生产者进程将一个数组中的十个数值发送到由5个缓冲区组成的共享内存中;

●两个消费者进程轮流接收并输出这十个数值,同时将两个消费者进程读出的数值进行累加求各和。

●考虑生产者进程生产的速度和消费者进程速度。

2.需求分析

生产者--消费者问题是一个著名的进程同步问题。

既然有进程间的同步,也就必将涉及到进程之间的互斥与通信问题,对于这个问题的解决有着很强的现实意义。

它的现实意义在于可以类比到计算机中对于临界资源的互斥共享。

生产者与消费者就好比是对计算机临界资源访问的程序或用户,而临界资源如打印机、磁带机等设备。

3.概要设计

3.1程序流程图

说明:

图3.1程序流程图所示,首先生产者与消费者线程创建,便就去访问缓冲区。

对于生产者若缓冲区没有被其他线程访问,且缓冲区未满则生产数据存放到缓冲区,若其中有一条件没有满足则生产者线程进入阻塞状态。

而对于消费者同样也需要缓冲区没有被其他线程访问,但同时要求缓冲区未空才能从缓冲区取数据,若其中有一个条件为满足则同样进入阻塞状态。

 

图3.1程序流程图

4.详细设计

4.1程序框架

4.1.1生产者与消费者的父类

publicclassSuperThreadextendsJPanel{

//定义缓冲区的读写锁

privateLockbufferLock;

//共享缓冲区

publicstaticIntBufferbuffer=IntBuffer.allocate(5);

//生产者数组

publicintarray[]={1,5,6,9,8,11,13,10,7,3};

//生产者执行的次数

publicstaticintcount=0;

//两个生产者取出数据的累加

publicstaticintconsumerSum=0;

//记录消费者取数次数

publicstaticintconsumerCount=0;

//存放从缓冲区中取得的数据

privatestaticintconsumerData;

//定义线程名

publicStringnameString;

//线程互斥信号,值为0表示生产者进程,值为1表示消费者进程

publicstaticintmutex=0;

/*构造函数*/

publicSuperThread(Stringname){

//主要完成一些变量的初始化

}

/*获得线程名*/

publicStringgetNameString(){

returnnameString;

}

/*设置线程名*/

publicvoidsetNameString(StringnameString){

this.nameString=nameString;

}

/*获得互斥信号*/

publicstaticintgetMutex(){

returnmutex;

}

/*设置互斥信号*/

publicstaticvoidsetMutex(intmutex){

SuperThread.mutex=mutex;

}

/*判断是否有线程访问缓冲区,没有则对线程进行加锁*/

publicbooleanwait(intmutex){

if(mutex==1){

returnfalse;

}else{

returntrue;

}

}

/*释放进程操作完成信号,其实本质就是修改mutex的信号值*/

publicstaticvoidsignal(){

mutex=0;

}

/*判断缓冲区是否为空*/

publicbooleanisBufferEmpty(){

//根据缓冲区中是否有0存在来判断是否为空

//若0的个数为5则为空,反之则不为空

}

/*判断缓冲区是否为满*/

publicbooleanisBufferFull(){

//根据缓冲区中是否有0存在来判断是否为空

//若0的个数为0则为满,反之则不满

}

/*消费数,即在缓冲区中取数*/

publicvoidconsume(){

if(wait(mutex)&&!

isBufferEmpty()){//判断是否访问缓冲区

//加锁

bufferLock.lock();

try{

//设置互斥信号

//从缓冲区取数

//将取数后的缓冲区置0

//释放互斥信号

}finally{

//解锁

bufferLock.unlock();

}

}

}

/*消费者取得缓冲区数据*/

publicintgetBufferData(intindex){

//完成取数操作

returndata;

}

/*生产数,即向缓冲区中存数*/

publicvoidproduce(){

if(wait(mutex)&&!

isBufferFull()){//判断是否访问缓冲区

bufferLock.lock();//加锁

try{

//设置互斥信号

//向缓冲区存数

//释放互斥信号

}finally{

//解锁

bufferLock.unlock();

}

}

}

/*生产者向公共缓冲区放数据*/

publicvoidputBufferData(intindex){

//完成想缓冲区存数操作

}

}

4.1.2生产者类

publicclassProducerextendsSuperThreadimplementsRunnable{

//生产者休眠时间

privateintproducerDelay;

/*生产者构造函数*/

publicProducer(Stringname){

super(name);

}

/*获得生产者休眠时间*/

publicintgetProducerDelay(){

returnproducerDelay;

}

/*设置生产者休眠时间*/

publicvoidsetProducerDelay(intproducerDelay){

this.producerDelay=producerDelay;

}

/*线程中的run函数,线程启动时默认调用的函数*/

@Override

publicvoidrun(){

//线程启动后向缓冲区存数操作

}

}

4.1.3消费者类

publicclassConsumerextendsSuperThreadimplementsRunnable{

/*消费者休眠时间*/

privateintconsumerDelay;

/*消费者构造函数*/

publicConsumer(Stringname){

super(name);

}

/*获得消费者休眠时间*/

publicintgetConsumerDelay(){

returnconsumerDelay;

}

/*设置消费者休眠时间*/

publicvoidsetConsumerDelay(intconsumerDelay){

this.consumerDelay=consumerDelay;

}

/*线程中的run函数,线程启动时默认调用的函数*/

@Override

publicvoidrun(){

while(true){

//线程启动后向缓冲区取数操作

}

}

4.1.4主程序入口

主函数main(String[]args){

//生产者与消费者对象定义producer、consumer1、consumer2

//设置休眠参数,如1000、2000、2500

//创建线程producerThread、consumer1Thread、consumer2Thread

//启动线程producerThread.start()、consumer1Thread.start()、

//consumer2Thread.start();

}

4.2基本算法分析

4.2.1wait(mutex)与signal()数值信号

数值信号wait(mutex)主要是通过整型值mutex的设置来表示缓冲区是否已被访问,具体过程为:

当有线程需要访问缓冲区时,先确定wait(mutex)信号值,若mutex的值为1则wait(mutex)为真,便可进行下一步操作,若mutex的值为0则wait(mutex)为不为真,该线程阻塞。

当线程完成对缓冲区的访问后需要调用signal()信号对信号值mutex进行释放,释放后mutex的值为1,以便其他线程能够访问缓冲区。

wait(mutex)与signal()的主要代码如下:

publicbooleanwait(intmutex){//wait(mutex)信号

if(mutex==1){

returnfalse;

}else{

returntrue;

}

}

publicstaticvoidsignal(){//signal()信号

mutex=0;

}

4.2.2isBufferEmpty()与isBufferFull()信号

对于以上所述的wait(mutex)信号还不足以控制线程之间的同步与互斥,还必须使用到isBufferEmpty()与isBufferFull()两个信号。

对于生产者要用到信号isBufferFull()来判断缓冲区是否为满,当wait(mutex)型号值为真且isBufferFull()信号值不为真时,生产者线程才能对缓冲区进行存数操作,否则就阻塞等待机会。

而对于消费者同样也要用到辅助信号isBufferEmpty()来判断缓冲区是否为空,只有缓冲区不为空且wait(mutex)为真是,消费者才能对缓冲区进行取数操作。

isBufferEmpty()与isBufferFull()的主要代码如下:

publicbooleanisBufferEmpty(){//判断缓冲区是否为空

intcount=0;

for(inti=0;i

if(buffer.get(i)==0){//根据缓冲区中的0的个数来判断,若缓

//区0的个数为5(缓冲区容量为5),则为空//反之不为空

count++;

}

}

if(count==5){

returntrue;

}else{

returnfalse;

}

}

publicbooleanisBufferFull(){//判断缓冲区是否为满

intcount=0;

for(inti=0;i

if(buffer.get(i)!

=0){//根据缓冲区中不为0的个数来判断,若缓

//区不为0的个数小于5(缓冲区容量为5),//则不为满,反之为满

count++;

}

}

if(count<5){

returnfalse;

}else{

returntrue;

}

}

4.2.3produce()存数方法与consume()取数方法

produce()方法由生产者使用,在条件满足的情况下对缓冲区进行存数操作,而这个条件就是wait(mutex)==true&&!

isBufferFull()==true。

对于消费者调用consume()方法同样也要满足这样一个条件:

wait(mutex)==true&&!

isBufferEmpty()==true。

produce()与consume()方法的主要代码如下:

/*生产数,即向缓冲区中存数*/

publicvoidproduce(){

if(wait(mutex)&&!

isBufferFull()){

bufferLock.lock();//对该程序段加锁,防止其他线程访问缓冲区

try{

setMutex

(1);//将线程互斥信号值mutex设置为1,使之互斥

intindex=0;

for(inti=0;i

if(buffer.get(i)==0){

index=i;

break;

}

}

putBufferData(index);//向缓冲区中存入数据

signal();//释放互斥信号,将mutex设置为0

}finally{

bufferLock.unlock();//解锁

}

}

}

/*消费数,即在缓冲区中取数*/

publicvoidconsume(){

if(wait(mutex)&&!

isBufferEmpty()){

bufferLock.lock();//对该程序段加锁,防止其他线程访问缓冲区

try{

setMutex

(1);//将线程互斥信号值mutex设置为1,使之互斥

intindex=0;//存放顺序查找第一个为0的数的下摆

inti;

for(i=0;i

if(buffer.get(i)==0){

index=i;

break;

}elseif(buffer.get(4)>0){//缓冲区为满的情况

index=5;

}

}

consumerData=getBufferData(index-1);//取数据

consumerCount++;

if(consumerCount<=2){

consumerSum=consumerSum+consumerData;//计算两次取数//之和

if(consumerCount==2){

System.out.println("消费者取数之和为:

"+consumerSum);

consumerSum=0;

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

当前位置:首页 > 求职职场 > 简历

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

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