广东工业大学操作技巧系统-实验报告-4份全.doc
.操作系统实验报告 学生学院_ 计算机学院_专业班级_10级计算机科学与技术5班学 号_3210006071_学生姓名_陈丹飞_指导教师_孙为军_ 2013年 1 月 10 日目录1 实验一 进程调度12 实验二 作业调度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 #define getpch(type) (type*)malloc(sizeof(type) #define NULL 0 struct pcb /* 定义进程控制块PCB */ char name10; /*定义进程名称*/ char state; /*进程状态*/ int super; /*优先数*/ int ntime; /*需要运行的时间*/ int rtime; /*已占用的CPU时间*/ struct pcb* link; *ready=NULL,*p; typedef struct pcb PCB; /*pcb表*/ sort() /* 建立对进程进行优先级排列函数*/ PCB *first, *second; int insert=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() /* 建立进程控制块函数*/ int i,num; clrscr(); /*清屏*/ printf(n 请输入进程号?); scanf(%d,&num); for(i=0;iname); 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函数*/ int space() int l=0; PCB* pr=ready; while(pr!=NULL) l+; pr=pr-link; return(l); disp(PCB * pr) /*建立进程显示函数,用于显示当前进程*/ printf(n qname t state t super t ndtime t runtime n); printf(|%st,pr-name); printf(|%ct,pr-state); printf(|%dt,pr-super); printf(|%dt,pr-ntime); printf(|%dt,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() /*主函数*/ int len, h=0; char ch; input(); len=space(); while(len!=0)&(ready!=NULL) ch=getchar(); h+; printf(n The execute number:%d n,h); p=ready; ready=p-link; p-link=NULL; p-state=R; check(); running(); printf(n 按任一键继续.); ch=getchar(); printf(nn 进程已经完成.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输入进程运行时间:1The execute number:1*当前正在运行的进程是:EQnamestatesuperndtimeruntimeER510*当前就绪队列状态为:QnamestatesuperndtimeruntimeDw410Bw310Aw210Cw110进程E已完成按任一键继续The execute number:2*当前正在运行的进程是:DQnamestatesuperndtimeruntimeDR410*当前就绪队列状态为:QnamestatesuperndtimeruntimeBw310Aw210Cw110进程D已完成按任一键继续The execute number:3*当前正在运行的进程是:BQnamestatesuperndtimeruntimeBR310*当前就绪队列状态为:QnamestatesuperndtimeruntimeAw210Cw110进程B已完成按任一键继续The execute number:4*当前正在运行的进程是:AQnamestatesuperndtimeruntimeAR210*当前就绪队列状态为:QnamestatesuperndtimeruntimeCw110进程A已完成按任一键继续The execute number:5*当前正在运行的进程是:cQnamestatesuperndtimeruntimecR110*当前就绪队列状态为:进程C已完成按任一键继续进程已经完成(二)、简单轮转法1、实验原理在分时系统中,都毫无例外采用时间片轮转法。在一种简单的轮转法中,系统将所有就绪进程按FIFO规则排成一个队列,把CPU分配给队首进程,并规定它执行一给定的时间如100ms,称此时间间隔为时间片。当时间片完成时,系统产生一个时钟中断,剥夺该进程的执行,将它送至就绪队列的末尾,并把处理机分配给就绪队列的新队首进程,同样也让它执行一个时间片。这样,就绪队列中的所有进程均可获得一个时间片的处理机而运行。就绪队列中的进程在依次执行时,可能发生以下三种情况:(1)进程未用完一个时间片就结束,这时系统应提前调度;(2)进程在执行过程中提出I/O请求而阻塞,系统应将它放入相应的阻塞队列并引起调度;(3)进程完成一个时间片后尚未完成,系统应将它重新放到就绪队列的末尾,等待下次执行。由于在分时系统中,键盘命令的执行时间较短,大多能在一个时间片内执行完毕,因此分时系统的实际响应时间将比Nq(N是同时性用户数,q是时间片大小)小。2、源代码:#include/*定义一个pcb的结构体*/struct pcb char name; /*进程名*/int time; /*进程执行时间*/; void main() int n,i,j,flag=1; struct pcb a100; /*最多可以有100个进程*/printf(输入进程个数:); scanf(%d,&n); getchar();/*接收回车*/ for(i=0;i0) /*若进程数为空,结束程序*/ if(ai.time!=0) /*就绪队列是否为空*/ printf(%c,ai.name); /*进程执行一次,打印出该进程*/ai.time-; /*使该进程占用的时间片减1*/ for(j=0;jn;j+) if(aj.time) /*若进程所占用的时间片不为0,仍执行下一进程*/ flag=1; break; else /*若进程所占用的时间片为0,说明已经完成,跳过执行下一进程*/flag=0; i=(+i)%n; /*继续执行下一个进程,i1*/ printf(n);3、运行结果:输入进程个数:5输入进程的名字:A输入占用的时间片:2输入进程的名字:B输入占用的时间片:3输入进程的名字:C输入占用的时间片:1输入进程的名字:D输入占用的时间片:4输入进程的名字:E输入占用的时间片:5ABCDEABDEBDEDEEPress any key to continue六、心得体会: 操作系统是计算机系统中必不可少的系统软件。它是计算机系统中各种资源的管理者和各种活动的组织者、指挥者。操作系统采用时间片法调度进程,使系统资源得到充分的利用,用户也可以花更少的时间完成更多的工作,通过这次进程调度实验,让我明白了系统时间片的调度方法,对操作系统理论的学习更加深一层.并且增强了用语言的编程能力。在编程的过程中,遇到了种种困难,并且一一的克服了,这使我产生很大的成就感。实验二 作业调度一、实验名称:进程调度用高级语言编写和调试一个或多个作业调度的模拟程序,加深对作业调度算法的理解。二、实验内容: 在单道批处理系统中,作业一投入运行,它就占有计算机的一切资源直到作业完成为止,因此调度作业时不必考虑它所需要的资源是否得到满足,它所占用的CPU时限等因素。而在多道批处理系统中,作业首先存放在外存,当系统拥有的资源足够分配给一个作业,就将资源分配给此作业,并将此作业调进内存。当系统资源不足以分配给一个作业时,则等待已经分配资源的作业运行完成后释放资源增加系统资源。(一)、为单道批处理系统设计一个作业调度程序1、实验原理。作业等待算法:分别采用先来先服务(FCFS),最短作业优先(SJF)、响应比高者优先(HRN)的调度算法。 (1)先来先服务(FCFS)算法先来先服务作业调度算法是一种较简单的作业调度算法,即每次调度是从后备作业队列中选择一个最先进入该队列的作业,将它调入内存,分配资源、创建相应的进程,放入进程就绪队列准备运行。FCFS算法利于长作业,不利于短作业,而大多数的作业是I/O繁忙的短作业。以FCFS作为主调度算法是不常用的。(2)短作业优先调度算法(SJF)短作业优先调度算法是指操作系统在进行作业调度时以作业长短作为优先级进行调度。该调度算法可以照顾到实际上占作业总数绝大部分的短作业,使它们能比长作业优先调度执行。这时后备作业队列按作业优先级由高到低顺序排列,当作业进入后备队列时要按该作业优先级放置到后备队列相应的位置。实践证明,该调度算法的性能是最好的,单位时间的作业吞吐量也最大,但也存在缺点:对长作业极为不利。(3)响应比高者优先(HRN)的调度算法采用响应比高者优先调度算法,进行调度时必须计算出系统中的所有满足必要条件作业的响应比;从中选择响应比最高的一个作业装入主存储器、分配资源,由于是实验,所以就用将作业的作业控制块出队,并输出作业的作业名代替装入主存储器,同时修改系统的资源数量;用同样方法选择第二个、第三个直到不再有满足必要条件的作业。调度算法的流程图如下 :2、源代码及运行结果:#include stdio.h#define getjcb(type) (type*)malloc(sizeof(type)#define NULL 0int n=0,time=0;float eti,ewi;struct jcb char name10; /* 作业名 */ char state; /* 作业状态 */ int ts; /* 提交时间 */ float super; /* 优先权 */ int tb; /* 开始运行时间 */ int tc; /* 完成时间 */ float ti; /* 周转时间 */ float wi; /* 带权周转时间 */ int ntime; /* 作业所需运行时间 */ struct jcb *link; /* 结构体指针 */ *p,*q,*head=NULL;typedef struct jcb JCB;inital()int i;printf(n输入作业数:n);scanf(%d,&n);printf(输入:n作业名t到达时间t服务时间n);for(i=0;iname,&p-ts,&p-ntime); p-state=W; p-link=NULL; if(head=NULL) head=q=p; else q-link=p; q=p; void print(JCB *pr,int m)JCB *p; printf(ntime=%d,time); if(m=3) printf(n作业名t状态t到达时间t服务时间t优先权tt完成时间t周转时间t带权周转时间n); printf(%st%ct%dt%dt%4.2ft%dt%4.2ft%4.2fn, pr-name,pr-state,pr-ts,pr-ntime,pr-super,pr-tc,pr-ti,pr-wi); else printf(n作业名 状态 到达时间 服务时间 完成时间 周转时间 带权周转时间n); printf(%st%ct%dt%dt%dt%4.2ft%4.2fn, 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(%st%ct%dt%dt%4.2fn, p-name,p-state,p-ts,p-ntime,p-super); else printf(%st%ct%dt%dn, 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(%st%ct%dt%dt%4.2ft%dt%4.2ft%4.2fn, p-name,p-state,p-ts,p-ntime,p-super,p-tc,p-ti,p-wi); elseprintf(%st%ct%dt%dt%dt%4.2ft%4.2fn, p-name,p-state,p-ts,p-ntime,p-tc,p-ti,p-wi); p=p-link; while(p!=NULL);void last()eti/=n;ewi/=n; printf(n平均周转时间%7.3fn平均带权周转时间=%7.3fn,eti,ewi);super()JCB *padv;padv=head;do if(padv-state=W&padv-tssuper=(float)(time-padv-ts+padv-ntime)/padv-ntime; padv=padv-link;while(padv!=NULL);void hrn(m)JCB *min;int i,iden;for(i=0;istate=W&p-tssupermin-super) min=p; p=p-link; while(p!=NULL); if(iden) i-;time+;printf(ntime=%d,time); if(time1000)printf(nruntime is too long.error.);getch(); else running(min,m); void sjf(int m) JCB *min; int i,iden; for(i=0;istate=W&p-tsntimentime) min=p; p=p-link; while(p!=NULL) ; if(iden) i-;printf(ntime=%d,time);time+; if(time100)printf(nruntime is too long.error);getch(); elserunning(min,m); fcfs(int m) int i,iden; for(i=0;istate=W&p-tslink; while(p!=NULL&iden) ; if(iden) i-;printf(ntime=%d,time);time+; if(time100)printf(nruntime is too long.error);getch(); else running(p,m); running(JCB *p,int m) p-tb=time;p-state=R; p-tc=p-tb+p-ntime; p-ti=(float)(p-tc-p-ts); p-wi=(float)(p-ti/p-ntime); eti+=p-ti; ewi+=p-wi; print(p,m); time+=p-ntime; p-state=F; printf(n作业%s已经完成!npress any key to continue.n,p-name); getch();void runjcb(int m) printf(nn作业开始运行); switch(m)case 1:fcfs(m);break; case 2:sjf(m);break; case 3:hrn(m);break; default:printf(n运行错误!n);exit(); start() int m; char str100=n选择调度算法:n1.先来先服务FCFSn2.最短作业优先SJFn3.响应比高者优先HRNn ; printf(%s,str); m=getch()-48; inital(); if(1=m&m=3) runjcb(m); else printf(n选择错误,请重新选择!n); start(); last();main()start(); printf(n所有作业完成!); getch();运行结果:1、选择先来先服务FCFS选择调度算法:1.先来先服务FCFS2.最短作业优先SJF3.响应比高者优先HRN输入作业数:5输入:作业名到达时间服务时间A04B13C25D32E44作业开始运行Time=0作业名 状态 到达时间 服务时间 完成时间 周转时间 带权周转时间AR044 4.001.00BW13CW25DW32EW44作业A已经完成Press any key to continueTime=4作业名 状态 到达时间 服务时间 完成时间 周转时间 带权周转时间BR137 6.002.00CW25DW32EW44AF044 4.001.00作业B已经完成Press any key to continueTime=7作业名 状态 到达时间 服务时间 完成时间 周转时间 带权周转时间CR25 12 10.002.00DW32EW44AF044 4.001.00BF137 6.002.00作业C已经完成Press any key to continueTime=12作业名 状态 到达时间 服务时间 完成时间 周转时间 带权周转时间DR321411.005.50EW44AF044 4.001.00BF137 6.002.00CF25 12 10.002.00作业D已经完成Press any key to continueTime=14作业名 状态 到达时间 服务时间 完成时间 周转时间 带权周转时间ER441814.003.50AF044 4.001.00BF137 6.002.00CF25 12 10.002.00DF321411.005.50作业E已经完成Press any key to continue平均周转时间9.000平均带权周转时间=2.800所有作业完成!2、选择最短作业优先SJF(简要过程) 作业开始运行Time=0作业名 状态 到达时间 服务时间 完成时间 周转时间 带权周转时间AR044 4.001.00BW13CW25DW32EW44作业A已经完成Press any key to continueTime=4作业名 状态 到达时间 服务时间 完成时间 周转时间 带权周转时间DR3263.001.50BW13CW25EW44AF044 4.001.00作业D已经完成Press any key to continueTime=6作业名 状态 到达时间 服务时间 完成时间 周转时间 带权周转时间Br1398.002.67CW25EW44AF044 4.001.00DF3263.001.50作业B已经完成Press any key to continueTime=9作业名 状态 到达时间 服务时间 完成时间 周转时间 带权周转时间ER44139.002.25CW25AF044 4.001.00BF1398.002.67DF3263.001.50作业E已经完成Press any key to continueTime=13作业名 状态 到达时间 服务时间 完成时间 周转时间 带权周转时间CR251816.003.20AF044 4.001.00BF1
收藏
- 资源描述:
-
^.
操作系统实验报告
学生学院____ 计算机学院______
专业班级_10级计算机科学与技术5班
学 号__3210006071__________
学生姓名___陈丹飞_____________
指导教师________孙为军_______
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
#define getpch(type) (type*)malloc(sizeof(type))
#define NULL 0
struct pcb { /* 定义进程控制块PCB */
char name[10]; /*定义进程名称*/
char state; /*进程状态*/
int super; /*优先数*/
int ntime; /*需要运行的时间*/
int rtime; /*已占用的CPU时间*/
struct pcb* link;
}*ready=NULL,*p;
typedef struct pcb PCB; /*pcb表*/
sort() /* 建立对进程进行优先级排列函数*/
{ PCB *first, *second;
int insert=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() /* 建立进程控制块函数*/
{ int i,num;
clrscr(); /*清屏*/
printf("\n 请输入进程号?");
scanf("%d",&num);
for(i=0;iname);
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函数*/
}
}
int space()
{ int l=0; PCB* pr=ready;
while(pr!=NULL)
{ l++;
pr=pr->link;
}
return(l);
}
disp(PCB * pr) /*建立进程显示函数,用于显示当前进程*/
{ printf("\n qname \t state \t super \t ndtime \t runtime \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() /*主函数*/
{ int len, h=0;
char ch;
input();
len=space();
while((len!=0)&&(ready!=NULL))
{ ch=getchar();
h++;
printf("\n The execute number:%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
The execute number:1
****当前正在运行的进程是:E
Qname state super ndtime runtime
E R 5 1 0
****当前就绪队列状态为:
Qname state super ndtime runtime
D w 4 1 0
B w 3 1 0
A w 2 1 0
C w 1 1 0
进程[E]已完成
按任一键继续……
The execute number:2
****当前正在运行的进程是:D
Qname state super ndtime runtime
D R 4 1 0
****当前就绪队列状态为:
Qname state super ndtime runtime
B w 3 1 0
A w 2 1 0
C w 1 1 0
进程[D]已完成
按任一键继续……
The execute number:3
****当前正在运行的进程是:B
Qname state super ndtime runtime
B R 3 1 0
****当前就绪队列状态为:
Qname state super ndtime runtime
A w 2 1 0
C w 1 1 0
进程[B]已完成
按任一键继续……
The execute number:4
****当前正在运行的进程是:A
Qname state super ndtime runtime
A R 2 1 0
****当前就绪队列状态为:
Qname state super ndtime runtime
C w 1 1 0
进程[A]已完成
按任一键继续……
The execute number:5
****当前正在运行的进程是:c
Qname state super ndtime runtime
c R 1 1 0
****当前就绪队列状态为:
进程[C]已完成
按任一键继续……
进程已经完成
(二)、简单轮转法
1、实验原理
在分时系统中,都毫无例外采用时间片轮转法。在一种简单的轮转法中,系统将所有就绪进程按FIFO规则排成一个队列,把CPU分配给队首进程,并规定它执行一给定的时间如100ms,称此时间间隔为时间片。当时间片完成时,系统产生一个时钟中断,剥夺该进程的执行,将它送至就绪队列的末尾,并把处理机分配给就绪队列的新队首进程,同样也让它执行一个时间片。这样,就绪队列中的所有进程均可获得一个时间片的处理机而运行。就绪队列中的进程在依次执行时,可能发生以下三种情况:(1)进程未用完一个时间片就结束,这时系统应提前调度;(2)进程在执行过程中提出I/O请求而阻塞,系统应将它放入相应的阻塞队列并引起调度;(3)进程完成一个时间片后尚未完成,系统应将它重新放到就绪队列的末尾,等待下次执行。由于在分时系统中,键盘命令的执行时间较短,大多能在一个时间片内执行完毕,因此分时系统的实际响应时间将比Nq(N是同时性用户数,q是时间片大小)小。
2、源代码:
#include
/*定义一个pcb的结构体*/
struct pcb
{ char name; /*进程名*/
int time; /*进程执行时间*/
};
void main()
{ int n,i,j,flag=1;
struct pcb a[100]; /*最多可以有100个进程*/
printf("输入进程 个数:");
scanf("%d",&n);
getchar();/*接收回车*/
for(i=0;i0) /*若进程数为空,结束程序*/
{ if(a[i].time!=0) /*就绪队列是否为空*/
{ printf("%c",a[i].name); /*进程执行一次,打印出该进程*/
a[i].time--; /*使该进程占用的时间片减1*/
}
for(j=0;jname,&p->ts,&p->ntime);
p->state=W;
p->link=NULL;
if(head==NULL) head=q=p;
else{
q->link=p;
q=p;
} }}
void print(JCB *pr,int m){
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);
}
void last(){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);
}
void hrn(m){JCB *min;
int i,iden;
for(i=0;istate==W&&p->ts<=time)
if(iden){ min=p;iden=0;}
else if(p->super>min->super) min=p;
p=p->link;
}while(p!=NULL);
if(iden) {i--;time++;printf("\ntime=%d",time);
if(time>1000){printf("\nruntime is too long...error...");getch();}
}
else{ running(min,m); }
}}
void sjf(int m){
JCB *min;
int i,iden;
for(i=0;istate==W&&p->ts<=time)
if(iden){ min=p;iden=0; }
else if(p->ntimentime) min=p;
p=p->link;
}while(p!=NULL) ;
if(iden) {i--;printf("\ntime=%d",time);time++;
if(time>100){printf("\nruntime is too long...error");getch();}
}
else{running(min,m);}
}}
fcfs(int m){ int i,iden;
for(i=0;istate==W&&p->ts<=time) iden=0;
if(iden)p=p->link;
}while(p!=NULL&&iden) ;
if(iden) { i--;printf("\ntime=%d",time);time++;
if(time>100){printf("\nruntime is too long...error");getch();}
}
else{ running(p,m); }
}}
running(JCB *p,int m){
p->tb=time;p->state=R;
p->tc=p->tb+p->ntime;
p->ti=(float)(p->tc-p->ts);
p->wi=(float)(p->ti/p->ntime);
eti+=p->ti;
ewi+=p->wi;
print(p,m);
time+=p->ntime;
p->state=F;
printf("\n作业%s已经完成!\npress any key to continue...\n",p->name);
getch();
}
void runjcb(int m){ printf("\n\n作业开始运行");
switch(m){case 1:fcfs(m);break;
case 2:sjf(m);break;
case 3:hrn(m);break;
default:printf("\n运行错误!\n");exit();
}}
start(){ int m;
char str[100]="\n选择调度算法:\n1.先来先服务FCFS\n2.最短作业优先SJF\n3.响应比高者优先HRN\n" ;
printf("%s",str);
m=getch()-48;
inital();
if(1<=m&&m<=3) runjcb(m);
else { printf("\n选择错误,请重新选择!\n");
start();
}
last();
}
main(){start();
printf("\n所有作业完成!");
getch();
}
运行结果:
1、选择先来先服务FCFS
选择调度算法:
1.先来先服务FCFS
2.最短作业优先SJF
3.响应比高者优先HRN
输入作业数:
5
输入:
作业名 到达时间 服务时间
A 0 4
B 1 3
C 2 5
D 3 2
E 4 4
作业开始运行
Time=0
作业名 状态 到达时间 服务时间 完成时间 周转时间 带权周转时间
A R 0 4 4 4.00 1.00
B W 1 3
C W 2 5
D W 3 2
E W 4 4
作业A已经完成
Press any key to continue…
Time=4
作业名 状态 到达时间 服务时间 完成时间 周转时间 带权周转时间
B R 1 3 7 6.00 2.00
C W 2 5
D W 3 2
E W 4 4
A F 0 4 4 4.00 1.00
作业B已经完成
Press any key to continue…
Time=7
作业名 状态 到达时间 服务时间 完成时间 周转时间 带权周转时间
C R 2 5 12 10.00 2.00
D W 3 2
E W 4 4
A F 0 4 4 4.00 1.00
B F 1 3 7 6.00 2.00
作业C已经完成
Press any key to continue…
Time=12
作业名 状态 到达时间 服务时间 完成时间 周转时间 带权周转时间
D R 3 2 14 11.00 5.50
E W 4 4
A F 0 4 4 4.00 1.00
B F 1 3 7 6.00 2.00
C F 2 5 12 10.00 2.00
作业D已经完成
Press any key to continue…
Time=14
作业名 状态 到达时间 服务时间 完成时间 周转时间 带权周转时间
E R 4 4 18 14.00 3.50
A F 0 4 4 4.00 1.00
B F 1 3 7 6.00 2.00
C F 2 5 12 10.00 2.00
D F 3 2 14 11.00 5.50
作业E已经完成
Press any key to continue…
平均周转时间=9.000
平均带权周转时间=2.800
所有作业完成!
2、选择最短作业优先SJF(简要过程)
… …
作业开始运行
Time=0
作业名 状态 到达时间 服务时间 完成时间 周转时间 带权周转时间
A R 0 4 4 4.00 1.00
B W 1 3
C W 2 5
D W 3 2
E W 4 4
作业A已经完成
Press any key to continue…
Time=4
作业名 状态 到达时间 服务时间 完成时间 周转时间 带权周转时间
D R 3 2 6 3.00 1.50
B W 1 3
C W 2 5
E W 4 4
A F 0 4 4 4.00 1.00
作业D已经完成
Press any key to continue…
Time=6
作业名 状态 到达时间 服务时间 完成时间 周转时间 带权周转时间
B r 1 3 9 8.00 2.67
C W 2 5
E W 4 4
A F 0 4 4 4.00 1.00
D F 3 2 6 3.00 1.50
作业B已经完成
Press any key to continue…
Time=9
作业名 状态 到达时间 服务时间 完成时间 周转时间 带权周转时间
E R 4 4 13 9.00 2.25
C W 2 5
A F 0 4 4 4.00 1.00
B F 1 3 9 8.00 2.67
D F 3 2 6 3.00 1.50
作业E已经完成
Press any key to continue…
Time=13
作业名 状态 到达时间 服务时间 完成时间 周转时间 带权周转时间
C R 2 5 18 16.00 3.20
A F 0 4 4 4.00 1.00
B F 1
展开阅读全文