广东工业大学操作系统实验报告4份全.docx
《广东工业大学操作系统实验报告4份全.docx》由会员分享,可在线阅读,更多相关《广东工业大学操作系统实验报告4份全.docx(81页珍藏版)》请在冰点文库上搜索。
广东工业大学操作系统实验报告4份全
操作系统实验报告
学生学院____计算机学院______
专业班级_10级计算机科学与技术5班
学号__**********__________
学生姓名___陈丹飞_____________
指导教师________孙为军_______
2013年1月10日
1实验一进程调度………………………………………………………………1
2实验二作业调度………………………………………………………………
3实验三可变式分区分配………………………………………………………
4实验四简单文件系统…………………………………………………………
试验一进程调度
一、实验目的:
编写和调试一个进程调度程序,以加深对进程的概念及进程调度算法的理解。
二、实验内容:
以两种典型算法为例说明实现的算法
(一)、最高优先数优先的调度算法
1、实验原理
进程调度算法:
采用最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)和先来先服务算法。
每个进程有一个进程控制块(PCB)表示。
进程控制块可以包含如下信息:
进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态等等。
进程的优先数及需要的运行时间可以事先人为地指定(也可以由随机数产生)。
进程的到达时间为进程输入的时间。
进程的运行时间以时间片为单位进行计算。
每个进程的状态可以是就绪W(Wait)、运行R(Run)、或完成F(Finish)三种状态之一。
就绪进程获得CPU后都只能运行一个时间片。
用已占用CPU时间加1来表示。
如果运行一个时间片后,进程的已占用CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低一级),然后把它插入就绪队列等待CPU。
每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的PCB,以便进行检查。
重复以上过程,直到所有进程都完成为止。
2、源代码:
#include"stdio.h"
#include
#include
#definegetpch(type)(type*)malloc(sizeof(type))
#defineNULL0
structpcb{/*定义进程控制块PCB*/
charname[10];/*定义进程名称*/
charstate;/*进程状态*/
intsuper;/*优先数*/
intntime;/*需要运行的时间*/
intrtime;/*已占用的CPU时间*/
structpcb*link;
}*ready=NULL,*p;
typedefstructpcbPCB;/*pcb表*/
sort()/*建立对进程进行优先级排列函数*/
{PCB*first,*second;
intinsert=0;
if((ready==NULL)||((p->super)>(ready->super)))/*优先级最大者,插入队首*/
{p->link=ready;
ready=p;
}
else/*进程比较优先级,插入适当的位置中*/
{first=ready;
second=first->link;
while(second!
=NULL)
{if((p->super)>(second->super))/*若插入进程比当前进程优先数大,*/
{/*插入到当前进程前面*/
p->link=second;
first->link=p;
second=NULL;
insert=1;
}
else/*插入进程优先数最低,则插入到队尾*/
{first=first->link;
second=second->link;
}
}
if(insert==0)first->link=p;
}
}
input()/*建立进程控制块函数*/
{inti,num;
clrscr();/*清屏*/
printf("\n请输入进程号?
");
scanf("%d",&num);
for(i=0;i{printf("\n进程号No.%d:
\n",i);
p=getpch(PCB);
printf("\n输入进程名:
");
scanf("%s",p->name);
printf("\n输入进程优先数:
");
scanf("%d",&p->super);
printf("\n输入进程运行时间:
");
scanf("%d",&p->ntime);
printf("\n");
p->rtime=0;p->state='w';
p->link=NULL;
sort();/*调用sort函数*/
}
}
intspace()
{intl=0;PCB*pr=ready;
while(pr!
=NULL)
{l++;
pr=pr->link;
}
return(l);
}
disp(PCB*pr)/*建立进程显示函数,用于显示当前进程*/
{printf("\nqname\tstate\tsuper\tndtime\truntime\n");
printf("|%s\t",pr->name);
printf("|%c\t",pr->state);
printf("|%d\t",pr->super);
printf("|%d\t",pr->ntime);
printf("|%d\t",pr->rtime);
printf("\n");
}
check()/*建立进程查看函数,检查等待队列的进程是否进入就绪队列*/
{PCB*pr;
printf("\n****当前正在运行的进程是:
%s",p->name);/*显示当前运行进程*/
disp(p);
pr=ready;
printf("\n****当前就绪队列状态为:
\n");/*显示就绪队列状态*/
while(pr!
=NULL)
{disp(pr);
pr=pr->link;
}
}
destroy()/*建立进程撤消函数(进程运行结束,撤消进程)*/
{printf("\n进程[%s]已完成.\n",p->name);
free(p);
}
running()/*建立进程就绪函数(进程运行时间到,置就绪状态*/
{(p->rtime)++;
if(p->rtime==p->ntime)
destroy();/*调用destroy函数*/
else
{(p->super)--;
p->state='w';
sort();/*调用sort函数*/
}
}
main()/*主函数*/
{intlen,h=0;
charch;
input();
len=space();
while((len!
=0)&&(ready!
=NULL))
{ch=getchar();
h++;
printf("\nTheexecutenumber:
%d\n",h);
p=ready;
ready=p->link;
p->link=NULL;
p->state='R';
check();
running();
printf("\n按任一键继续......");
ch=getchar();
}
printf("\n\n进程已经完成.\n");
ch=getchar();
}
3、运行结果:
请输入进程号?
5
进程号No.0:
输入进程名:
A
输入进程优先数:
2
输入进程运行时间:
1
进程号No.1:
输入进程名:
B
输入进程优先数:
3
输入进程运行时间:
1
进程号No.2:
输入进程名:
C
输入进程优先数:
1
输入进程运行时间:
1
进程号No.3:
输入进程名:
D
输入进程优先数:
4
输入进程运行时间:
1
进程号No.4:
输入进程名:
E
输入进程优先数:
5
输入进程运行时间:
1
Theexecutenumber:
1
****当前正在运行的进程是:
E
Qnamestatesuperndtimeruntime
ER510
****当前就绪队列状态为:
Qnamestatesuperndtimeruntime
Dw410
Bw310
Aw210
Cw110
进程[E]已完成
按任一键继续……
Theexecutenumber:
2
****当前正在运行的进程是:
D
Qnamestatesuperndtimeruntime
DR410
****当前就绪队列状态为:
Qnamestatesuperndtimeruntime
Bw310
Aw210
Cw110
进程[D]已完成
按任一键继续……
Theexecutenumber:
3
****当前正在运行的进程是:
B
Qnamestatesuperndtimeruntime
BR310
****当前就绪队列状态为:
Qnamestatesuperndtimeruntime
Aw210
Cw110
进程[B]已完成
按任一键继续……
Theexecutenumber:
4
****当前正在运行的进程是:
A
Qnamestatesuperndtimeruntime
AR210
****当前就绪队列状态为:
Qnamestatesuperndtimeruntime
Cw110
进程[A]已完成
按任一键继续……
Theexecutenumber:
5
****当前正在运行的进程是:
c
Qnamestatesuperndtimeruntime
cR110
****当前就绪队列状态为:
进程[C]已完成
按任一键继续……
进程已经完成
(二)、简单轮转法
1、实验原理
在分时系统中,都毫无例外采用时间片轮转法。
在一种简单的轮转法中,系统将所有就绪进程按FIFO规则排成一个队列,把CPU分配给队首进程,并规定它执行一给定的时间如100ms,称此时间间隔为时间片。
当时间片完成时,系统产生一个时钟中断,剥夺该进程的执行,将它送至就绪队列的末尾,并把处理机分配给就绪队列的新队首进程,同样也让它执行一个时间片。
这样,就绪队列中的所有进程均可获得一个时间片的处理机而运行。
就绪队列中的进程在依次执行时,可能发生以下三种情况:
(1)进程未用完一个时间片就结束,这时系统应提前调度;
(2)进程在执行过程中提出I/O请求而阻塞,系统应将它放入相应的阻塞队列并引起调度;(3)进程完成一个时间片后尚未完成,系统应将它重新放到就绪队列的末尾,等待下次执行。
由于在分时系统中,键盘命令的执行时间较短,大多能在一个时间片内执行完毕,因此分时系统的实际响应时间将比Nq(N是同时性用户数,q是时间片大小)小。
2、源代码:
#include
/*定义一个pcb的结构体*/
structpcb
{charname;/*进程名*/
inttime;/*进程执行时间*/
};
voidmain()
{intn,i,j,flag=1;
structpcba[100];/*最多可以有100个进程*/
printf("输入进程个数:
");
scanf("%d",&n);
getchar();/*接收回车*/
for(i=0;i{printf("输入进程的名字:
\n");
scanf("%c",&a[i].name);/*以字符接收进程名*/
getchar();/*接收回车*/
printf("输入占用的时间片:
");/*输入进程占用的时间片*/
scanf("%d",&a[i].time);
getchar();/*接收回车*/
}
i=0;
while(flag&&n>0)/*若进程数为空,结束程序*/
{if(a[i].time!
=0)/*就绪队列是否为空*/
{printf("%c",a[i].name);/*进程执行一次,打印出该进程*/
a[i].time--;/*使该进程占用的时间片减1*/
}
for(j=0;jif(a[j].time)/*若进程所占用的时间片不为0,仍执行下一进程*/
{flag=1;
break;
}
else/*若进程所占用的时间片为0,说明已经完成,跳过执行下一进程*/
flag=0;
i=(++i)%n;/*继续执行下一个进程,i+1*/
}
printf("\n");
}
3、运行结果:
输入进程个数:
5
输入进程的名字:
A
输入占用的时间片:
2
输入进程的名字:
B
输入占用的时间片:
3
输入进程的名字:
C
输入占用的时间片:
1
输入进程的名字:
D
输入占用的时间片:
4
输入进程的名字:
E
输入占用的时间片:
5
ABCDEABDEBDEDEE
Pressanykeytocontinue
六、心得体会:
操作系统是计算机系统中必不可少的系统软件。
它是计算机系统中各种资源的管理者和各种活动的组织者、指挥者。
操作系统采用时间片法调度进程,使系统资源得到充分的利用,用户也可以花更少的时间完成更多的工作,通过这次进程调度实验,让我明白了系统时间片的调度方法,对操作系统理论的学习更加深一层.并且增强了用C语言的编程能力。
在编程的过程中,遇到了种种困难,并且一一的克服了,这使我产生很大的成就感。
实验二作业调度
一、实验名称:
进程调度
用高级语言编写和调试一个或多个作业调度的模拟程序,加深对作业调度算法的理解。
二、实验内容:
在单道批处理系统中,作业一投入运行,它就占有计算机的一切资源直到作业完成为止,因此调度作业时不必考虑它所需要的资源是否得到满足,它所占用的CPU时限等因素。
而在多道批处理系统中,作业首先存放在外存,当系统拥有的资源足够分配给一个作业,就将资源分配给此作业,并将此作业调进内存。
当系统资源不足以分配给一个作业时,则等待已经分配资源的作业运行完成后释放资源增加系统资源。
(一)、为单道批处理系统设计一个作业调度程序
1、实验原理。
作业等待算法:
分别采用先来先服务(FCFS),最短作业优先(SJF)、响应比高者优先(HRN)的调度算法。
(1)先来先服务(FCFS)算法
先来先服务作业调度算法是一种较简单的作业调度算法,即每次调度是从后备作业队列中选择一个最先进入该队列的作业,将它调入内存,分配资源、创建相应的进程,放入进程就绪队列准备运行。
FCFS算法利于长作业,不利于短作业,而大多数的作业是I/O繁忙的短作业。
以FCFS作为主调度算法是不常用的。
(2)短作业优先调度算法(SJF)
短作业优先调度算法是指操作系统在进行作业调度时以作业长短作为优先级进行调度。
该调度算法可以照顾到实际上占作业总数绝大部分的短作业,使它们能比长作业优先调度执行。
这时后备作业队列按作业优先级由高到低顺序排列,当作业进入后备队列时要按该作业优先级放置到后备队列相应的位置。
实践证明,该调度算法的性能是最好的,单位时间的作业吞吐量也最大,但也存在缺点:
对长作业极为不利。
(3)响应比高者优先(HRN)的调度算法
采用响应比高者优先调度算法,进行调度时必须计算出系统中的所有满足必要条件作业的响应比;从中选择响应比最高的一个作业装入主存储器、分配资源,由于是实验,所以就用将作业的作业控制块出队,并输出作业的作业名代替装入主存储器,同时修改系统的资源数量;用同样方法选择第二个、第三个……直到不再有满足必要条件的作业。
调度算法的流程图如下:
2、源代码及运行结果:
#include"stdio.h"
#definegetjcb(type)(type*)malloc(sizeof(type))
#defineNULL0
intn=0,time=0;floateti,ewi;
structjcb{charname[10];/*作业名*/
charstate;/*作业状态*/
intts;/*提交时间*/
floatsuper;/*优先权*/
inttb;/*开始运行时间*/
inttc;/*完成时间*/
floatti;/*周转时间*/
floatwi;/*带权周转时间*/
intntime;/*作业所需运行时间*/
structjcb*link;/*结构体指针*/
}*p,*q,*head=NULL;
typedefstructjcbJCB;
inital(){inti;
printf("\n输入作业数:
\n");
scanf("%d",&n);
printf("输入:
\n作业名\t到达时间\t服务时间\n");
for(i=0;iscanf("%s\t%d\t%d",&p->name,&p->ts,&p->ntime);
p->state='W';
p->link=NULL;
if(head==NULL)head=q=p;
else{
q->link=p;
q=p;
}}}
voidprint(JCB*pr,intm){
JCB*p;
printf("\ntime=%d",time);
if(m==3){printf("\n作业名\t状态\t到达时间\t服务时间\t优先权\t\t完成时间\t周转时间\t带权周转时间\n");
printf("%s\t%c\t%d\t%d\t%4.2f\t%d\t%4.2f\t%4.2f\n",
pr->name,pr->state,pr->ts,pr->ntime,pr->super,pr->tc,pr->ti,pr->wi);
}
else{printf("\n作业名状态到达时间服务时间完成时间周转时间带权周转时间\n");
printf("%s\t%c\t%d\t%d\t%d\t%4.2f\t%4.2f\n",
pr->name,pr->state,pr->ts,pr->ntime,pr->tc,pr->ti,pr->wi);
}
p=head;
do{if(p->state=='W')
if(m==3){printf("%s\t%c\t%d\t%d\t%4.2f\n",
p->name,p->state,p->ts,p->ntime,p->super);
}
else{printf("%s\t%c\t%d\t%d\n",
p->name,p->state,p->ts,p->ntime);
}
p=p->link;
}while(p!
=NULL);
p=head;
do{if(p->state=='F')
if(m==3){
printf("%s\t%c\t%d\t%d\t%4.2f\t%d\t%4.2f\t%4.2f\n",
p->name,p->state,p->ts,p->ntime,p->super,p->tc,p->ti,p->wi);
}
else{printf("%s\t%c\t%d\t%d\t%d\t%4.2f\t%4.2f\n",
p->name,p->state,p->ts,p->ntime,p->tc,p->ti,p->wi);
}
p=p->link;
}while(p!
=NULL);
}
voidlast(){eti/=n;ewi/=n;
printf("\n平均周转时间=%7.3f\n平均带权周转时间=%7.3f\n",eti,ewi);
}
super(){JCB*padv;
padv=head;
do{if(padv->state=='W'&&padv->ts<=time)
padv->super=(float)(time-padv->ts+padv->ntime)/padv->ntime;
padv=padv->link;
}while(padv!
=NULL);
}
voidhrn(m){JCB*min;
inti,iden;
for(i=0;isuper();
do{if(p->state=='W'&&p->ts<=time)
if(iden){min=p;iden=0;}
elseif(p->super>min->super)min=p;
p=p->link;
}while(p!
=NULL);
if(iden){i--;time++;printf("\ntime=%d",time);
if(time>1000){printf("\nruntimeistoolong...error...");getch();}
}
else{running(min,m);}
}}
voidsjf(intm){
JCB*min;
inti,iden;
for(i=0;ido{if(p->state=='W'&&p->ts<=time)
if(iden){min=p;iden=0;}
elseif(p->ntimentime)min=p;
p=p->link;
}wh