haihongyuan.com
海量文库 文档专家
全站搜索:
您现在的位置:首页 > 小学教育 > 学科竞赛学科竞赛

苹果-桔子问题的实现 (2)

发布时间:2013-12-28 13:00:57  

*******************

实践教学

*******************

兰州理工大学

计算机与通信学院

2013年秋季学期

操作系统原理课程设计

专业班级:计算机科学与技术

姓 名:

学 号:

成 绩:_____________

摘要

本设计实际上是生产者-消费者问题的一种变形。这里,生产者(父亲和母亲)放入缓冲区(盘子)的产品有两类(苹果和桔子),消费者(女儿和儿子)也有两类,每类消费者只消费其中固定的一类产品。生产者和消费者共享缓冲区,缓冲区中有空时,生产者可放入产品(不许放重),否则等待。缓冲区中有产品时,消费者可取出产品(不许取重),否则等待。

关键词:进程同步;PV操作;互斥;信号量

I

目录

摘要 ................................................................................................................................................... I

第一章 需求分析 ............................................................................................................................. 1

1.1吃水果问题的描述 ............................................................................................................ 1

1.2问题的转换 ........................................................................................................................ 1

第二章 功能设计 ............................................................................................................................. 1

2.1 数据结构 ........................................................................................................................... 1

2.2模块说明 ............................................................................................................................ 2

2.2.1 主函数 ................................................................................................................... 2

2.2.2 4个调度进程函数 .............................................................................................. 2

2.3 操作的流程图 ................................................................................................................... 3

2.3.1放水果操作 ........................................................................................................ 3

2.3.2取水果操作 ........................................................................................................ 5

2.4 P、V原语的描述 ............................................................................................................ 5

第3章 各模块的伪码算法 ............................................................................................................. 7

3.1 算法设计 ........................................................................................................................... 7

3.1.1 父亲进程模块 ....................................................................................................... 7

3.1.2 母亲进程模块 ....................................................................................................... 7

3.1.3 儿子进程模块 ....................................................................................................... 8

3.1.5 Print函数 ............................................................................................................ 8

第4章 开发平台及程序清单的主要部分 ................................................................................... 9

4.1开发平台 .......................................................................................................................... 9

第5章 运行结果与运行情况分析 ............................................................................................. 10

5.1运行结果 ........................................................................................................................ 10

课程设计总结 ............................................................................................................................. 12

参考文献......................................................................................................................................... 13

附录:部分源程序代码 ................................................................................................................. 14

第一章 需求分析

1.1吃水果问题的描述

桌上有一个空盘子,只允许放一个水果。爸爸专向盘中放苹果,妈妈专向盘中放桔子,儿子专等吃盘中的桔子,女儿专等吃盘中的苹果。规定当盘空时,一次只能放一个水果。

1.2问题的转换

这是进程同步问题的模拟,可以把向盘子放或取水果的每一个过程可以转为一个进程的操作,这些进程是互斥的,同时也存在一定的同步关系。通过编程实践时,实际是随机的调用人一个进程的操作,而这些进程的操作相当于程序中的函数调用。而计算机在执行时每一个时刻只能执行一个操作,这就默认了互斥。同步的模拟可以类似于函数调用时的前提关系即先决条件。这样进程同步模拟就完全可以通过函数的调用来实现。

具体的每一个操作的对应的函数的关系:

爸爸向盘子中放一个苹果:Father()

妈妈向盘子中放一个橘子:Mother()

儿子从盘子取一个橘子:Son()

女儿从盘子取一个苹果:Daugther()

第二章 功能设计

2.1 数据结构

(1)用一个整型变量Plate_Size表示盘子的水果量,初始值为0,当放水果时Plate_Size加1,取水果时Plate_Size减1。变量Plate_Size的最大值为1,当为1时表示盘子已经满,此时若进行放水果操作,放水果将处于等待状态;为0时表示盘子为空,此时若进行取水果操作,取水果操作将处于等待状态。 1

(2)整型变量orange和apple分别表示盘子中的橘子和苹果数目,初始都为0,orange表示儿子的私有信号量,apple表示女儿的私有信号量,盘子中水果总量为Plate_Size=apple+orange。

(3)用4个bool型的变量 Father_lag,Mother_lag,Son_lag,Daughter_lag表示四个进程是否处于等待状态。处于等待时,变量值为true。

(4)两个放水果进程进程同时处于等待状态时,若有取水果的操作将自动执行等待的放水果进程,执行按等待的先后顺序;取苹果或橘子进程同时候处于等待状态,若有放苹果或橘子的操作将自动执行等待的取进程,进行按等待的先后顺序。

(5)用一个随机的函数产生0—3的4个整数,分别对应四个进程的调用。

2.2模块说明

2.2.1 主函数

用一个随机的函数产生0—3的4个整数,分别对应四个进程的调用,调用

的次数可以自己输入,本程序共产生了10次随机的调用进程。

2.2.2 4个调度进程函数

爸爸向盘子中放一个苹果操作:Father()

妈妈向盘子中放一个橘子操作:Mother()

儿子从盘子取一个橘子操作:Son()

女儿从盘子取一个苹果操作:Daugther()

2.2.3 Print函数

用于输出盘子中苹果和橘子的个数,水果总个数及有哪些进程处于等待状态。

2

2.3 操作的流程图

2.3.1放水果操作

爸爸放苹果进程的操作流程图:

图2.1爸爸放苹果进程的操作流程图

3

妈妈放桔子进程的操作流程图:

图2.2 妈妈放桔子进程的操作流程图

4

2.3.2取水果操作

儿子取橘子的操作流程图:

图2.3 儿子取橘子的操作流程图

2.4 P、V原语的描述

Semaphore Plate_Siz

Semaphore apple

Semaphore orange

Father() {

5

While(ture) {

P(Plate_Siz)

P(mutex)

父亲向盘子中放进一个苹果 V(apple)

V(mutex)

}

}

Mother() {

While(ture) {

P(Plate_Siz)

P(mutex)

母亲向盘子中放进一个桔子 V(orange)

V(mutex)

}

}

Son(i) {

While(ture) {

P(Plate_Siz)

P(mutex)

P(apple)

儿子从盘子中走一个桔子 V(orange)

V(mutex)

}

}

6

Daugther () {

While(ture) {

P(Plate_Siz)

P(mutex)

女儿从盘子中走一个苹果 V(apple) V(mutex)

}

}

第3章 各模块的伪码算法

3.1 算法设计

3.1.1 父亲进程模块

void Father() //Father进程 {

}

3.1.2 母亲进程模块

void Mother() //Mother进程 {

orange++; Print(); apple++; Print();

}

7

3.1.3 儿子进程模块

void Son() //Son进程

{

orange--; Print();

}

3.1.4 女儿进程模块

void Daughter() //Daughter进程

{

apple--; Print();

}

3.1.5 Print函数

void Print() //Print函数(打印盘子剩余水果及各进程等待状态)

{

cout<<"现在盘子里有"<<apple<<"个苹果,"<<orange<<"个橘子,"<<"共有"<<apple+orange<<"个水果."<<endl;

if(Father_lag==true) cout<<"Father进程处于等待状态,"; if(Mother_lag==true) cout<<"Mother进程处于等待状态,"; if(Son_lag==true) cout<<"Son进程处于等待状态,"; if(Daughter_lag==true) cout<<"Daughter进程处于等待状态,";

if(((Father_lag==false)&&(Mother_lag==false)&&(Son_lag==false)&&(Daughter_lag==false))!=true)

8

cout<<endl;

}

第4章 开发平台及程序清单的主要部分

4.1开发平台

(1)使用系统:Windows XP

(2)使用语言:C++

(3)开发工具:Visual C++ 6.0

9

第5章 运行结果与运行情况分析

5.1运行结果

第一次运行结果为:

图5.1 第一次运行结果

10

第二次运行结果:

图5.2 第二次运行结果

11

课程设计总结

在本次设计中,首先分析问题并把问题转化为编程问题;其次用了随机函数来调用相应的进程函数,这对进程间的同步和等待状态有很好的说明;再次设了四个bool型的变量来表示各进程时候处于等待状态,还设置了相应的整型变量来解决等待进程在适当的条件下自动调用的先后问题。

在本次设计中,首先使我提高了分析问题,并根据需求转化成相应的程序结构的能力;其次也丰富了自己编写程序,调试程序的经验,这使得我编程时可能出现的错误的认识,并如何去避免产生了新的认识。

在本次设计中除了可以用随机函数来产生随机数来调用相应的进程函数,也可以用人输入的方式来选择调用相应的进程函数,这样可以会麻烦些,不过对进程同步的模拟可能会更加透彻。

总的来说这次设计比较成功,加深我对进程的理解,同时也提高了自己的编程的能力。编程是个长久的过程,平时要多去动手实践,去提高自己分析问题、发现问题、解决问题的能力

12

参考文献

1. 汤子瀛,哲凤屏.《计算机操作系统》.西安电子科技大学学出版社.

2. 王清,李光明.《计算机操作系统》.冶金工业出版社.

3. 孙钟秀等. 操作系统教程. 高等教育出版社

5. 张丽芬,刘利雄.《操作系统实验教程》. 清华大学出版社.

6. 孟静, 操作系统教程--原理和实例分析. 高等教育出版社

7. 周长林,计算机操作系统教程. 高等教育出版社

8. 张尧学,计算机操作系统教程,清华大学出版社

9. 任满杰,操作系统原理实用教程,电子工业出版社

13

附录:部分源程序代码

#include<time.h> //用到了time函数,所以要有这个头文件

#include<stdlib.h> //用到了srand函数,所以要有这个头文件

#include<iostream.h>

int Plate_Size=0; //表示盘子中当前有几个水果

int orange=0,apple=0; //表示盘子中orange和apple的个数

bool Father_lag,Mother_lag,Son_lag,Daughter_lag; //四个进程处于等待时,变量值为true void main() //main()函数,实现其他功能函数的调用

{

void Print(); //函数声明

void Father();

void Mother();

void Son();

void Daughter();

int k;

srand((unsigned)time(NULL));//srand()函数产生一个以当前时间开始的随机种子 for(k=0;k<10;k++)

{

cout<<"第"<<k+1<<"次操作:"<<endl; //printf("第%d次操作:\n",k+1);

int i=rand()%4; //随进生成4以内的整数,即0-3的4个整数

Plate_Size=apple+orange;

int MonFa_c,Daughter_b,Son_a; //for语句的局部变量,控制进程等待的优先次序,MonFa_c=2,Mather()执行,MonFa_c=1,Father()执行

switch(i) //0为Father()调用,1为Mother()调用,2为Son(),3为Daughter()调用

{

case 0:

cout<<"Father调用."<<endl;

if(Plate_Size==1)

{

Father_lag=true; //Father()等待

Print();

if(Mother_lag==false)

MonFa_c=1;

}

else

{

Father();

if(Daughter_lag==true)

14

{

if(Daughter_b==1)

{

Daughter_lag=false;//Daughter等待取消

Daughter(); //处于等待的Daughter自动调用

}else Daughter_b=0; }else Daughter_b=0; //没有等待的Dauther进程 }

break;

case 1:

cout<<"Mother调用."<<endl;

if(Plate_Size==1)

{

Mother_lag=true; //Mother()等待

Print();

if(Father_lag==false)

MonFa_c=2;

}

else

{

Mother();

if(Son_lag==true) //Son等待

{

if(Son_a==1) //Son执行

{

Son_lag=false;//Son等待取消

Son(); //处于等待的Son()自动调用

} else Son_a=0;

} else Son_a=0;

}

break;

case 2:

cout<<"Son调用."<<endl;

if(orange==0)

{

Son_lag=true; //Son处于等待

Print();

}

else

{

15

Son();

if((Father_lag==true)&&(Mother_lag==true))

{

if(MonFa_c==1) //Father和Mother同时处于等待,但Father先等待,因此先调用

{

Father_lag=false;

Father();

MonFa_c=2;

}

else //Father和Mother同时处于等待,但Mother先等待,因此先调用

{

Mother_lag=false;

Mother();

MonFa_c=1;

}

}

else

{

if(Father_lag==true) //只有Father处于等待,调用

{

Father_lag=false;

Father();

MonFa_c=0;

}

else if(Mother_lag==true)//只有Mother处于等待,调用 {

Mother_lag=false;

Mother();

MonFa_c=0;

}

}

}

break;

case 3:

cout<<"Daughter调用."<<endl;

if(apple==0)

{

Daughter_lag=true; //Daughter等待

Print();

Daughter_b=1;

16

}

else

{

Daughter();

if((Father_lag==true)&&(Mother_lag==true))

{

if(MonFa_c==1) //Father和Mother同时处于等待,但Father先等待,因此先调用

{

Father_lag=false;

Father();

MonFa_c=2;

}

else //Father和Mother同时处于等待,但Mother先等待,因此先调用

{

Mother_lag=false;

Mother();

MonFa_c=1;

}

}

else

{

if(Father_lag==true) //只有Father处于等待,调用 {

Father_lag=false;

Father();

MonFa_c=0;

}

else if(Mother_lag==true) //只有Mother处于等待,调用 {

Mother_lag=false;

Mother();

MonFa_c=0;

}

}

}

break;

} //switch语句结束

} //for语句结束

} //main函数结束

void Print() //Print函数(打印盘子剩余水果及各进程等待状态)

{

17

cout<<"现在盘子里有"<<apple<<"个苹果,"<<orange<<"个橘子,"<<"共有"<<apple+orange<<"个水果."<<endl;

if(Father_lag==true)

cout<<"Father进程处于等待状态,";

if(Mother_lag==true)

cout<<"Mother进程处于等待状态,";

if(Son_lag==true)

cout<<"Son进程处于等待状态,";

if(Daughter_lag==true)

cout<<"Daughter进程处于等待状态,";

if(((Father_lag==false)&&(Mother_lag==false)&&(Son_lag==false)&&(Daughter_lag==false))!=true)

cout<<endl;

}

void Father() //Father进程

{

apple++;

Print();

}

void Mother() //Mother进程

{

orange++;

Print();

}

void Son() //Son进程

{

orange--;

Print();

}

void Daughter() //Daughter进程

{

apple--;

Print();

}

18

19

网站首页网站地图 站长统计
All rights reserved Powered by 海文库
copyright ©right 2010-2011。
文档资料库内容来自网络,如有侵犯请联系客服。zhit326@126.com