操作系统实习报告.docx
《操作系统实习报告.docx》由会员分享,可在线阅读,更多相关《操作系统实习报告.docx(31页珍藏版)》请在冰豆网上搜索。
操作系统实习报告
操作系统原理实习报告
实习一银行家算法
实习二多级队列调度算法
学院:
姓名:
学号:
班级:
指导教师:
实习一银行家算法
【问题描述】
1、概念
安全状态:
系统按照某种序列为多个进程分配资源直到最大需求,如果能够保证所有进程全部顺利执行完毕,则称系统是安全的。
2、采取的数据结构
(1)可利用资源量Available
(2)最大需求矩阵Max
(3)分配矩阵Allocation[i]
(4)需求矩阵Need[i]
(5)请求矩阵Request[i]
3、银行家算法
设request:
是Pi进程的请求向量,当Pi发了资源请求后,系统按下述步骤检查:
(1)如果Request[i]<=Need[i],则转向步骤
(2);
(2)若Request[i]<=Available,则转向步骤(3);
(3)系统试探性地把要求的资源分配给进程Pi,并修改以下数据结构的值:
Available=Available-Request[i];
Allocation[i]=Allocation[i]+Request[i];
Need[i]=Need[i]-Request[i];
(4)系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态,若安全,才正式将资源分配给Pi进程,完成本次分配;否则,试探性分配作废,恢复原来的资源分配状态,Pi进程进入等待状态。
4、安全性算法
(1)设置两个向量:
工作向量work,它表示系统可提供给进程继续运行所需的各类资源数目,执行安全性算法开始时,work初值=Available;finish表示系统是否有足够的资源分配给里程,使之运行完成,开始时,finish[i]=false;当有足够资源分配给进程时,令finish[i]=true;
(2)从进程集合中找到满足下述条件的进程:
finish[i]=false;
Need[i]<=work;若找到执行(3),否则执行(4);
(3)当进程Pi获得资源后,顺序执行直到完成,并释放它的资源,执行:
work=work+Allocation[i];
finish[i]=true;
gotostep
(2);
(4)若所有进程的finish[i]=true,则系统处于安全状态,否则,处于不安全状态。
【测试数据】
a.进程P2请求资源(0,3,4)
b进程P4请求资源(1,0,1)
c.进程P1请求资源(2,0,1)
d.进程P3请求资源(0,0,2)
【实现提示】
(1)将各部分设计成子函数,然后调用,可以使结构清晰。
(2)将向量和矩阵存储在一维数组和二维数组中。
一、需求分析
1.将向量和矩阵存储在一维数组和二维数组中。
2.用户输入数据,并且可以决定测试的数据数量。
3.安全性算法可以决定拟分配是否实行。
4.要求测试四组数据。
二、设计
1.设计思想
1.银行家算法
(1)存储结构:
用数组来存储向量和矩阵。
(2)主要算法基本思想:
设request:
是Pi进程的请求向量,当Pi发了资源请求后,系统按下述步骤检查:
(1)如果Request[i]<=Need[i],则转向步骤
(2);
(2)若Request[i]<=Available,则转向步骤(3);
(3)系统试探性地把要求的资源分配给进程Pi,并修改以下数据结构的值:
Available=Available-Request[i];
Allocation[i]=Allocation[i]+Request[i];
Need[i]=Need[i]-Request[i];
(4)系统执行安全性算法,设置两个向量:
工作向量work,它表示系统可提供给进程继续运行所需的各类资源数目,执行安全性算法开始时,work初值=Available;finish表示系统是否有足够的资源分配给里程,使之运行完成,开始时,finish[i]=false;当有足够资源分配给进程时,令finish[i]=true;从进程集合中找到满足下述条件的进程:
finish[i]=false;Need[i]<=work;若找到执行(5),否则执行(6);(5)当进程Pi获得资源后,顺序执行直到完成,并释放它的资源,执行:
work=work+Allocation[i];
finish[i]=true;
gotostep(6);
(6)若所有进程的finish[i]=true,则系统处于安全状态,否则,处于不安全状态。
检查此次资源分配后,系统是否处于安全状态,若安全,才正式将资源分配给Pi进程,完成本次分配;否则,试探性分配作废,恢复原来的资源分配状态,Pi进程进入等待状态。
2、安全性算法
(1)设置两个向量:
工作向量work,它表示系统可提供给进程继续运行所需的各类资源数目,执行安全性算法开始时,work初值=Available;finish表示系统是否有足够的资源分配给里程,使之运行完成,开始时,finish[i]=false;当有足够资源分配给进程时,令finish[i]=true;
(2)从进程集合中找到满足下述条件的进程:
finish[i]=false;
Need[i]<=work;若找到执行(3),否则执行(4);
(3)当进程Pi获得资源后,顺序执行直到完成,并释放它的资源,执行:
work=work+Allocation[i];
finish[i]=true;
gotostep
(2);
(4)若所有进程的finish[i]=true,则系统处于安全状态,否则,处于不安全状态。
2.设计表示
(1)函数调用关系图
main->Bijiao
main->safe
(2)函数接口规格说明
intBijiao(inti)/*比较请求与需求矩阵*/
intsafe(inth)/*安全性算法*/
3.实现注释
(1)根据输入的进程号和所申请的资源数来对向量进行比较;
(2)符合要求则进行拟分配,否则输出进程阻塞;
(3)进行安全性算法检测,不安全则撤销分配,否则实行分配;
4.详细设计
#define n 5 //进程个数
#define m 3 //资源种类
int Available[m],Alloc[n][m],Need[n][m];
main()
{
intrequest[m];
input();
while
(1)
{
read_req();
if (请求结束) break;
(1)if(!
(requesti<=Needi)) 表示非法请求;
(2)if(!
(requesti<=Availablei))则Pi阻塞;
(3)试探性分配
Available=Available-Requesti;
Alloci=Alloci+Requesti;
Needi=Needi-Requesti;
(4)若新状态安全,则实际分配资源给Pi,否则取消试探性分配。
}
}
安全状态判别算法:
(1)设置Finish=(false,...,false)work=Available
(2)循环查找满足下列条件的进程pi //最多循环n次
Finish[i]=false且Needi<=work
(3)若找到则 Finish[i]=true;work=work+Alloci;转
(2)
(4)若Finish=(true,...,true)则安全,否则不安全。
测试数据:
m=3:
种类型的资源(A,B,C,);进程个数n=5;Available=(2,3,3);
已分配资源数量
资源需求量
ABC
ABC
P1
212
347
P2
402
134
P3
305
003
P4
204
221
P5
314
110
5.流程图
是
否
是
否是
三、调试分析
遇到的问题:
在测试数据时,一直显示的是进程阻塞。
解决办法:
产生这一现象的原因是在安全性算法失败时,没有撤销拟分配的资源,只要加上撤销资源的步骤就可以解决这一问题。
四、用户手册
点击运行程序会显示如下提示:
根据提示依次输入进程号,会有如下显示:
按照提示输入进程所申请的资源量:
则第一个进程的处理就完成了:
五、运行结果
六、源程序清单
#include
#include
#definen5//总进程数
#definem3//总资源数
#defineFALSE0
#defineTRUE1
intMax[n][m];
intAvailable[m]={2,2,3};//系统可用资源数
intAllocation[n][m]={{2,1,2},{4,0,2},{3,0,5},{2,0,4},{3,1,4}};//n个进程已经得到N类资源的资源量
intNeed[n][m]={{3,4,7},{1,3,4},{0,0,3},{2,2,1},{1,1,0}};//n个进程还需要m类资源的资源量
intRequest[m];//请求矩阵
intBijiao(inti);
intsafe();
voidmain()
{
inta,b,c,d;
inti=0,j=0,k;
while
(1)
{
printf("请输入需申请资源的进程号:
");
scanf("%d",&i);
printf("请输入进程%d申请的资源数",i);
scanf("%d%d%d",&Request[0],&Request[1],&Request[2]);
a=Bijiao(i);
if(a)
{
for(k=0;k{
Available[k]=Available[k]-Request[k];
Allocation[i-1][k]=Allocation[i-1][k]+Request[k];
Need[i-1][k]=Need[i-1][k]-Request[k];
}
safe(i);
}
}
}
intBijiao(inti)//比较请求与需求矩阵
{
intj;
intm=0,n=0;
for(j=0;j{
if((Request[j]<=Need[i-1][j]))
m++;
if((Request[j]<=Available[j]))
n++;
}
if(m==3&&n==3)
return1;
else
printf("该进程阻塞!
\n");
return0;
}
intsafe(inth)
{
intwork[m],Finish[n];
inti=0,j,k=0;
for(i=0;iFinish[i]=FALSE;
for(j=0;jwork[j]=Available[j];
//i=s;
while(i{
k=0;
for(j=0;j{
if(Finish[j]==FALSE&&Need[j][0]<=work[0]&&Need[j][1]<=work[1]&&Need[j][2]<=work[2])
{
Finish[j]=TRUE;
work[0]=Allocation[j][0];
work[1]=Allocation[j][1];
work[2]=Allocation[j][2];
}
}
for(j=0;jif(Finish[j]=TRUE)
k++;
if(k==n)
break;
else
i++;
}
k=0;
for(i=0;i{
if(Finish[i]==TRUE)
k++;
}
if(k!
=n)
{
printf("该进程阻塞!
\n");
for(j=0;j{
Available[j]=Available[j]+Request[j];Allocation[h-1][j]=Allocation[h-1][j]-Request[j];
Need[h-1][j]=Need[h-1][j]+Request[j];
}
}
else
{
printf("新状态稳定,资源实际分配!
\n");
}
return0;
}
实习二多级队列调度算法
【问题描述】
设RQ分为RQ1和RQ2,RQ1采用轮转法,时间q=7.RQ1>RQ2,RQ2采用短进程优先调度算法。
RQ1:
P1-P5,RQ2:
P6-P10。
【测试数据】
测试数据如下:
RQ1:
P1-P5,RQ2:
P6-P10
进程
P1
P2
P3
P4
P5
P6
P7
P8
P9
P10
运行时间
16
11
14
13
15
21
18
10
7
14
已等待时间
6
5
4
3
2
1
2
3
4
5
一、需求分析
1.将p1-p5、p6-p10做成链表,并把各个进程的运行时间和已等待时间保存到节点中;
2.当RQ1中的进程没有结束时,将进程排到队列末尾;
3.对于RQ2中的进程需要按照运行时间由小到大的顺序排序;
4.运行程序,输出结果。
二、设计
1.设计思想
(1)存储结构:
单链表
(2)主要算法基本思想:
对单链表的指针进行操作。
2.详细设计
typedef struct tag_pcb
{
char name[8];
intneed;//须运行的时间
intturn;//周转时间
struct tag_pcb *next;
}PCB;
PCB *RQ1,*RQ2;
intclock=0; //时钟
main()
{
输入RQ1;
输入RQ2;(最好从文件读入)
while(RQ1!
=NULL)
{
从RQ1中选取一进程Pi准备运行;
计算其运行的时间t;
clock+=t; //表示Pi运行t;
if(Pi完成) 计算其turn;
否则 Pi加入到队尾;
}
while(RQ2!
=NULL)
{
从RQ2中选取一进程Pi准备运行;
clock+=Pi.need;
计算Pi的turn;
}
输出进程的周转时间;
}
3.流程图
否
是
否
是
三、调试分析
遇到的问题:
当在vs2008上调试时,出现了结果一闪而过的问题,而在vc6.0上则没有此现象,上网查阅资料得知这是因为我使用的是程序调试,也就是按的F5键,要想显示dos下运行的结果,只需要按CTRL+F5直接运行就可以了。
问题解决之后,程序运行无误,结果也能正常显示了。
四、用户手册
点击运行程序,直接显示结果。
五、运行结果
六、源程序清单
#include
#include
typedefstructtag_pcb
{
charname[8];
intneed;
intturn;
intwait;
structtag_pcb*next;
}PCB;
PCB*RQ1,*RQ2;
intclock=0;
intListInitiate()
{
PCB*l,*p;
inti;
if((l=(PCB*)malloc(sizeof(PCB)))==NULL)
{
printf("内存不足!
");
return0;
}
RQ1=l;
p=l;
printf("请输入循环队列进程的名称、运行时间和已等待的时间:
");
scanf("%s%d%d",p->name,&p->need,&p->wait);
for(i=0;i<4;i++)
{
if((l=(PCB*)malloc(sizeof(PCB)))==NULL)
{
printf("内存不足!
");
return0;
}
p->next=l;
p=l;
printf("请输入循环队列进程的名称、运行时间和已等待的时间:
");
scanf("%s%d%d",p->name,&p->need,&p->wait);
}
RQ2=l;
p=RQ2;
for(i=0;i<5;i++)
{
if((l=(PCB*)malloc(sizeof(PCB)))==NULL)
{
printf("内存不足!
");
return0;
}
p->next=l;
p=p->next;
printf("请输入采用最短作业法进程的名称、运行时间和已等待的时间:
");
scanf("%s%d%d",p->name,&p->need,&p->wait);
}
p->next=NULL;
return1;
}
voidmain()
{
intm=5;intn=5;intq=7;
PCB*p,*s,*l,*s1,*p1;
inta[100];inti=0,j=0,t;
t=ListInitiate();
if(t)
{
p=RQ1;
for(i=0;i{
a[i]=p->need;
p=p->next;
}
for(i=0;i{
while(a[j]==0&&j{
j++;
p=p->next;
}
while(p!
=RQ2->next&&a[j]!
=0&&j{
if(a[j]>q)
{
a[j++]=a[j]-q;
clock+=q;
p=p->next;
}
else
{
clock+=a[j];
p->turn=clock+p->wait;
a[j++]=0;
p=p->next;
}
}
j=0;
p=RQ1;
}
l=RQ2;
s=RQ2->next;
s1=l;
p1=s;
p=p1->next;
while(s->next!
=NULL)
{
while(p!
=NULL)//找到运行时间最短的进程
{
if(s->need>p->need)
{
s=p;
s1=p1;
}
p1=p1->next;p=p->next;
}
s1->next=s->next;
s->next=l->next;
l->next=s;
l=l->next;
s1=s;
s=s->next;
p1=s;
p=s->next;
}
p=RQ2->next;
while(p!
=NULL)//RQ2的周转时间
{
clock+=p->need;
p->turn=clock+p->wait;
p=p->next;
}
p=RQ1;
while(p!
=RQ2->next)
{
printf("%s的周转时间为%d\n",p->name,p->turn);
p=p->next;
}
printf("\n");
p=RQ2->next;
while(p!
=NULL)
{
printf("%s的周转时间为%d\n",p->name,p->turn);
p=p->next;
}
}
elseprintf("Error!
");
}
心得体会
通过这次课程设计,不仅让我更加深入的了解了银行家算法、安全性算法、多级队列调度算法,更重要的还让我学会了、或者说是验证了“做事一定要有次序和对事物的总体把握”这句话。
开始我一味的进行调试,急切的想侥幸调试出来,但由于没有进行深入的考虑,我调试了很久都没没有成功,我仔细的分析题目,分析材料,在原由的基础上我进行了改正,终于调试成功了,虽然这个过程还是经过了一翻努力,当然汗水还是留的很值,这次操作系统实习,不仅让我对操作系统这门课程有了更深入的研究、对很多重要的概念有了巩固和掌握,还给了我今后做事的启示。
做事要塌实,不能想着一步登天,要有计划,有目的的进行做事。
我们应该认真找到自己的缺点并且及时改正。
此时此刻,我心里多了些成就感。
这是我整个学习过程中的一次经验、一次总结,我相信它肯定会给我今后的学习有所启示和指导作用。