
设计名称:
专业班级:
姓 名:
学 号:
起止时间:
成 绩 评 定
考核
| 内容 | 设计 表现 | 设计 报告 | 答辩 | 综合评 定成绩 |
| 成 绩 |
计算机科学与技术系
报告正文
一、设计目的
通过课程设计, 加深学生对操作系统各资源管理模块的理解,掌握操作系统的基本原理及功能。要求学生从给定的题目中选择至少三个题目进行设计,并给出设计思想、设计规范、算法描述、源程序以及运行示例。
二、设计内容
1、银行家算法
(1)设计思路
(1) 当一个顾客对资金的最大需求量不超过银行家现有的资金时就可接纳该顾客;
(2) 顾客可以分歧贷款,但贷款的总数不能超过最大需求量;
(3) 当银行家现有的资金不能满足顾客尚需的贷款数额时,对顾客的贷款可推迟支付,但总能使顾客在有限的时间里得到贷款;
(4) 当顾客得到所需的全部资金后,一定能在有限的时间里归还所有的资金.
操作系统按照银行家制定的规则为进程分配资源,当进程首次申请资源时,要测试该进程对资源的最大需求量,如果系统现存的资源可以满足它的最大需求量则按当前的申请量分配资源,否则就推迟分配。当进程在执行中继续申请资源时,先测试该进程已占用的资源数与本次申请的资源数之和是否超过了该进程对资源的最大需求量。若超过则拒绝分配资源,若没有超过则再测试系统现存的资源能否满足该进程尚需的最大资源量,若能满足则按当前的申请量分配资源,否则也要推迟分配。设进程cusneed提出请求REQUEST [i],则银行家算法按如下规则进行判断。
(1)如果REQUEST [cusneed] [i]<= NEED[cusneed][i],则转(2);否则,出错。
(2)如果REQUEST [cusneed] [i]<= AVAILABLE[cusneed][i],则转(3);否则,出错。
(3)系统试探分配资源,修改相关数据:
AVAILABLE[i]-=REQUEST[cusneed][i];
ALLOCATION[cusneed][i]+=REQUEST[cusneed][i];
NEED[cusneed][i]-=REQUEST[cusneed][i];
(4)系统执行安全性检查,如安全,则分配成立;否则试探险性分配作废,系统恢复原状,进程等待。
安全性检查算法
(1)设置两个工作向量Work=AVAILABLE;FINISH
(2)从进程集合中找到一个满足下述条件的进程,
FINISH==false;
NEED<=Work;
如找到,执行(3);否则,执行(4)
(3)设进程获得资源,可顺利执行,直至完成,从而释放资源。
Work+=ALLOCATION;
Finish=true;
GOTO 2
(4)如所有的进程Finish= true,则表示安全;否则系统不安全。
(2)结果
2 、哲学家就餐
(1)设计思路
进程同步是多道程序环境下一个十分重要的问题,而哲学家进餐问题则是经典的进程同步问题之一。哲学家进餐问题描述了5个哲学家的生活状态。哲学家的生活方式是交替进行思考和就餐。5个哲学家围坐在一张圆桌周围,圆桌上有5支筷子。平时哲学家处于思考状态,饥饿时便试图取其左右两边的筷子进餐,进餐完毕则继续思考。如果未能获取左右两支筷子则不能进餐只能等待。哲学家进餐问题描述了并发进程处理共享资源的问题。值得注意的是对共享资源的使用必须避免死锁的产生。
(2)结果
3、按时间片轮转法实现处理器调度的程序
(1)设计思路
依据设计功能要求,把五个进程按顺序排成循环队列,用指针next、head指定队列连接情况。用switch来选定首先开始执行的进程,在case中定义指针p所指向的pcb,当选定开始执行的pcb后,则开始对该pcb执行RunTime+1,如果RunTime与RequestTime相等或RequestTime=0时,则status为’E’,该pcb将退出队列,执行PcbNum-1。用flag来使用while循环语句,当flag=1时满足循环条件,当且仅当队列中的进程数PcbNum>0时,继续执行pcb的循环队列,否则队列空,程序结束;当不满足flag=1时,退出循环,结束程序。
假设队列为(a,b,c,d,e,a) b是被选中首先开始运行的pcb,执行RunTime+1,则该时刻b是队头pcb,队列变成(b,c,d,e,a,b),接着执行c,队列为(c,d,e,a,b,c),接着如此类推,但若执行c后,c进程的RunTime=RequestTime,则c应退出队列,PcbNum-1,执行状态为‘E’:q->status='E';指向c的指针将改为指向d(假设d未退出队列)q->head->next=q->next;q->next->head=q->head; 当PcbNum=0时,队列为空,则程序结束。
(2)结果
四、附录(程序源代码)
(1)银行家算法
#include "string.h"
#include "iostream"
using namespace std;
#define FALSE 0
#define TRUE 1
#define W 10
#define R 20
int M ; //总进程数
int N ; //资源种类
int ALL_RESOURCE[W];//各种资源的数目总和
int MAX[W][R]; //M个进程对N类资源最大资源需求量
int AVAILABLE[R]; //系统可用资源数
int ALLOCATION[W][R]; //M个进程已经得到N类资源的资源量
int NEED[W][R]; //M个进程还需要N类资源的资源量
int Request[R]; //请求资源个数
void showdata() //函数showdata,输出资源分配情况
{
int i,j;
cout<<"各种资源的总数量(all):"< for (j=0;j for (j=0;j cout<<"进程p"< for (j=0;j cout< cout<<"进程p"< for (j=0;j cout< void changdata(int k) //函数changdata,改变可用资源和已经拿到资源和还需要的资源的值 { int j; for (j=0;j AVAILABLE[j]=AVAILABLE[j]-Request[j]; ALLOCATION[k][j]=ALLOCATION[k][j]+Request[j]; NEED[k][j]=NEED[k][j]-Request[j];}} void rstordata(int k) //函数rstordata,恢复可用资源和已经拿到资源和还需要的资源的值 {int j; for (j=0;j ALLOCATION[k][j]=ALLOCATION[k][j]-Request[j]; NEED[k][j]=NEED[k][j]+Request[j];}} int chkerr(int s) //函数chkerr,检查是否安全 {int WORK,FINISH[W]; int i,j,k=0; for(i=0;i WORK=AVAILABLE[j]; i=s; do { if(FINISH[i]==FALSE&&NEED[i][j]<=WORK) { WORK=WORK+ALLOCATION[i][j]; FINISH[i]=TRUE; i=0; } else { i++; } }while(i { cout< } } cout< } void bank() //银行家算法 { int i=0,j=0; char flag='Y'; while(flag=='Y'||flag=='y') { i=-1; while(i<0||i>=M) { cout<<"请输入需申请资源的进程号(从P0到P"< if(i<0||i>=M)cout<<"输入的进程号不存在,重新输入!"< cout<<"请输入进程P"< for (j=0;j cout<<"资源"< if(Request[j]>NEED[i][j]) //若请求的资源数大于进程还需要i类资源的资源量j { cout<<"进程P"< cout<<"申请不合理,出错!请重新选择!"< break; } else { if(Request[j]>AVAILABLE[j]) //若请求的资源数大于可用资源数 { cout<<"进程P"< cout<<"申请不合理,出错!请重新选择!"< break; } } } if(flag=='Y'||flag=='y') { changdata(i); //调用changdata(i)函数,改变资源数 if(chkerr(i)) //若系统安全 { rstordata(i); //调用rstordata(i)函数,恢复资源数 showdata(); //输出资源分配情况 } else //若系统不安全 showdata(); //输出资源分配情况 } else //若flag=N||flag=n showdata(); cout< cin>>flag; } } void main() //主函数 { int i=0,j=0,p; cout<<"请输入总进程数:"< cout<<"请输入总资源种类:"< cout<<"请输入总资源数(all_resource):"< cout<<"依次输入各进程所需要的最大资源数量(max):"< for (j=0;j do { cin>>MAX[i][j]; if (MAX[i][j]>ALL_RESOURCE[j]) cout< } } cout<<"依次输入各进程已经占据的资源数量(allocation):"< for (j=0;j do { cin>>ALLOCATION[i][j]; if (ALLOCATION[i][j]>MAX[i][j]) cout< } } //初始化资源数量 for (j=0;j for (i=0;i p=p-ALLOCATION[i][j];//减去已经被占据的资源 AVAILABLE[j]=p; if(AVAILABLE[j]<0) AVAILABLE[j]=0; } } M;i++) for(j=0;j showdata(); bank(); } (2)学家就餐 #include #include #include void main() { int x1,x2;//1-5的随机数 int i,N;//N循环次数 int flag=-1;//flag记录信号量的全局变量 printf("请输入循环次数N:"); scanf("%d",&N); for(i=1;i<=N;i++) { x1=rand()%5+1; if(flag==-1) { printf("\\n第%d次循环第%d个哲学家可以单独进餐!",i,x1); flag=x1; } x2=rand()%5+1; if(flag==-1) { printf("\\n第%d次循环第%d个哲学家可以单独进餐!",i,x2); flag=x2; } else if(abs(flag-x2)==2||abs(flag-x2)==3) { printf("\\n第%d次循环第%d个和第%d个哲学家可以同时进餐!",i,flag,x2); flag=x2; } else printf("\\n第%d次循环第%d个哲学家思考!",i,x2); printf("\\n"); } } (3)时间片轮转实现处理器调度的程序 1、#include #include #define NULL 0 char Name[5]={'a','b','c','d','e'}; int Super[5]={3,5,7,10,6}; 2、////定义PCB struct PCB { char name;//PCB名字 int RunTime;//PCB已运行时间 int RequestTime;//PCB要求运行时间 int super;//PCB优先级 char status;//PCB状态 struct PCB* head;//指向上一个PCB结构体的指针变量 struct PCB* next;//指向下一个PCB结构体的指针变量 }; 3、struct PCB pcb1,pcb2,pcb3,pcb4,pcb5,*p,*q;/////////定义5个PCB进程 ////定义PCB各参数的初值,输入各个进程的运行时间 Value() { ///定义PCB名 pcb1.name=Name[0]; pcb2.name=Name[1]; pcb3.name=Name[2]; pcb4.name=Name[3]; pcb5.name=Name[4]; ///定义PCB优先级 pcb1.super=Super[0]; pcb2.super=Super[1]; pcb3.super=Super[2]; pcb4.super=Super[3]; pcb5.super=Super[4]; ///定义PCB状态,初态为'R' pcb1.status='R'; pcb2.status='R'; pcb3.status='R'; pcb4.status='R'; pcb5.status='R'; ///定义PCB运行时间,初值为0 pcb1.RunTime=0; pcb2.RunTime=0; pcb3.RunTime=0; pcb4.RunTime=0; pcb5.RunTime=0; ///给PCB的要求运行时间赋值 cout< cout<<"***第二个PCB "< cout<<"***第三个PCB "< cout<<"***第四个PCB "< cout<<"***第五个PCB "< cout<<"------------------------------------参数定义完毕-------------------------------"< ///////////使PCB连接成循环队列 Connect() { ///////PCB的前驱 pcb1.head=&pcb5; pcb2.head=&pcb1; pcb3.head=&pcb2; pcb4.head=&pcb3; pcb5.head=&pcb4; ////////PCB的后续 pcb1.next=&pcb2; pcb2.next=&pcb3; pcb3.next=&pcb4; pcb4.next=&pcb5; pcb5.next=&pcb1; } 4、///////显示输入 display() { cout<<"----------------------------------------------------------------"< cout<<" 要求时间"<<" 优先级"<<" 状态"< 5、/////PCB执行 Run() { Value(); Connect(); // struct PCB pcb1,pcb2,pcb3,pcb4,pcb5,*p,*q; char a; int num,n,PcbNum=5,Number=5,flag=1;//PcbNum表示进程执行过程中进程的个数,n表示已执行完毕的进程个数 q=NULL; //flag=1时程序继续 cout< cin>>num; cout< { case 1: p=&pcb1; break; case 2: p=&pcb2; break; case 3: p=&pcb3; break; case 4: p=&pcb4; break; case 5: p=&pcb5; break; } 6、 while (flag==1){ n=1; if((p->RequestTime==0)||(p->RequestTime==p->RunTime)){///要求运行时间为0或要求运行时间=运行时间时status='E' p->status='E'; } else{ //否则,运行时间+1 p->RunTime=p->RunTime+1; } cout<<"***进程运行情况如下所示:"< while(n<=PcbNum){ if((p->RequestTime==0)||(p->RequestTime==p->RunTime)){///要求运行时间为0或要求运行时间=运行时间时status='E' p->status='E'; } cout<<"\"< cout<<"\ "< q=p; Number=Number-1; } p=p->next;//指向下一进程 n++; PcbNum=Number; } if(q!=NULL){ if(q->RunTime==q->RequestTime){//有一个进程块执行完毕 q->status='E'; q->head->next=q->next; q->next->head=q->head; cout<<"*************************进程"< q=p; } else{ p=p->next; } } if(q==NULL){ p=p->next; } if(PcbNum!=0){ flag=0; cout<<"***要继续运行程序请按Enter键两次......"< 7、 if(a==getchar()){ flag=1; } else{ cout<<"***输入错误!!!"< } } if(PcbNum==0){ flag=0; cout<<"*********************进程经已全部执行完毕!**********************"< } } 8、main() { //Value(); // Connect(); Run(); }
