一、目的和要求
1. 实验目的
(1)加深对作业调度算法的理解;
(2)进行程序设计的训练。
2.实验要求
用高级语言编写一个或多个作业调度的模拟程序。
单道批处理系统的作业调度程序。作业一投入运行,它就占有计算机的一切资源直到作业完成为止,因此调度作业时不必考虑它所需要的资源是否得到满足,它所运行的时间等因素。
二、实验内容
根据指定的实验课题,完成设计、编码和调试工作,完成实验报告。
三、实验环境
可以采用TC,也可以选用Windows下的利用各种控件较为方便的VB,VC等可视化环境。也可以自主选择其他实验环境。
四、实验原理及核心算法参考程序段
#include "iostream.h"
#include "windows.h"
//#define N 3
typedef struct{
int ID;
int PRIORITY;
int CPUTIME;
int ALLTIME;
int STARTBLOCK;
int BLOCKTIME;
int STATE;//0-运行 1-阻塞 2-就绪 3-结束 4-未到达
int REACH;
int TIME;
}PROCESS;
void textcolor (int color)
{
SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), color );
}
void main(){
int i,time,max,l,l1,time1,flag=0,total=0,N,server[10],sum=0;
PROCESS pro[10];
textcolor(13);
cout<<"注意:本程序中状态代表如下"<<endl<<"0-运行 1-阻塞 2-就绪 3-结束 4-未到达"<<endl<<endl;
textcolor(15);
cout<<"请输入进程数:";
cin>>N;
cout<<"请设置时间片长度:";
cin>>time;
cout<<"请输入各进程初始状态:"<<endl;
cout<<"ID PRIORITY REACH ALLTIME STARTBLOCK BLOCKTIME"<<endl;
for(i=0;i<N;i++){
pro[i].CPUTIME=0;
pro[i].TIME=0;
cin>>pro[i].ID>>pro[i].PRIORITY>>pro[i].REACH;
cin>>pro[i].ALLTIME>>pro[i].STARTBLOCK>>pro[i].BLOCKTIME;
server[i]=pro[i].ALLTIME;
if(pro[i].REACH==0) pro[i].STATE=0;
else pro[i].STATE=4;
}
do{
cout<<endl<<"当前时刻为:"<<total;
textcolor(12);
cout<<endl<<"========================各进程状态为======================"<<endl;
textcolor(15);
cout<<"ID PRIORITY CPUTIME ALLTIME STARTBLOCK BLOCKTIME STATE"<<endl;
for(i=0;i<N;i++){
cout<<pro[i].ID<<" "<<pro[i].PRIORITY<<" "<<pro[i].CPUTIME<<" ";
cout<<pro[i].ALLTIME<<" "<<pro[i].STARTBLOCK<<" "<<pro[i].BLOCKTIME<<" "<<pro[i].STATE;
cout<<endl;
}
total+=time;
for(i=0;i<N;i++){
if(pro[i].STATE==4&&pro[i].REACH<total){
pro[i].STATE=1;
}
}
for(i=0;i<N;i++){
time1=pro[i].ALLTIME;
if(pro[i].STATE==0){
if(pro[i].ALLTIME<=time){
//pro[i].CPUTIME+=time1;
pro[i].ALLTIME=0;
pro[i].STATE=3;
pro[i].TIME=total-time+time1;
}
else{
//pro[i].CPUTIME+=time;
pro[i].ALLTIME-=time;
pro[i].STARTBLOCK--;
if(pro[i].STARTBLOCK==0){
pro[i].STATE=1;
pro[i].BLOCKTIME=time1;
pro[i].STARTBLOCK=time1;
}
pro[i].PRIORITY-=3;
pro[i].TIME=total;
}
}
if(pro[i].STATE==1){
pro[i].BLOCKTIME--;
if(pro[i].BLOCKTIME==0) pro[i].STATE=2;
pro[i].TIME=total;
}
if(pro[i].STATE==2){
//pro[i].CPUTIME+=time;
pro[i].PRIORITY++;
pro[i].TIME=total;
}
}
max=-100;
l1=-1;
l=-1;
for(i=0;i<N;i++){
if(pro[i].PRIORITY>max&&(pro[i].STATE==0||pro[i].STATE==2)){
l=i;
max=pro[i].PRIORITY;
}
if(pro[i].STATE==0) l1=i;
}
if(l!=-1&&l!=l1) pro[l].STATE=0;
if(l1!=-1) pro[l1].STATE=2;
flag=0;
for(i=0;i<N;i++){
if(pro[i].STATE!=3){
flag=1;
break;
}
}
if(flag==0) break;
}while(1);
cout<<endl<<"当前时刻:"<<total;
textcolor(12);
cout<<endl<<"========================各进程状态为======================"<<endl;
textcolor(15);
cout<<"ID PRIORITY CPUTIME ALLTIME STARTBLOCK BLOCKTIME STATE"<<endl;
for(i=0;i<N;i++){
cout<<pro[i].ID<<" "<<pro[i].PRIORITY<<" "<<pro[i].CPUTIME<<" ";
cout<<pro[i].ALLTIME<<" "<<pro[i].STARTBLOCK<<" "<<pro[i].BLOCKTIME<<" "<<pro[i].STATE;
cout<<endl;
}
cout<<endl<<"各进程运行结束!"<<endl;
cout<<"进程号 到达时间 结束时间 周转时间 带权周转时间"<<endl;
textcolor(10);
for(i=0;i<N;i++){
cout<<" "<<pro[i].ID<<" "<<pro[i].REACH<<" "<<pro[i].TIME<<" "<<pro[i].TIME-pro[i].REACH<<" "<<(float)(pro[i].TIME-pro[i].REACH)/server[i]<<endl;
sum+=pro[i].TIME-pro[i].REACH;
}
cout<<"平均周转时间为:"<<(float)sum/N<<endl;
textcolor(15);
}
进程优先数PRIORITY表示,并规定优先数越大的进程,其优先权越高。 队列指针NEXT用来将PCB排成队列。而为了清楚地观察每个进程的调度过程,程序应将每个时间片内的进程的情况显示出来,包括正在运行的进程,处于就绪队列中的进程和处于阻塞队列中的进程。
不同的时间片,周转时间就会不同,对一个进程来说,一个重要的指标是它执行所需要的时间. 从进程提交到进程完成的时间间隔就是周转时间.也就是等待进入内存的时间,在就绪队列中等待的时间,在 CPU中执行的时间和I/O操作的时间的总和.
通过调度程序的实现,了解进程是如何运转,每调度一次进程cpu所占用时间都会加1,以及更熟练的掌握优先级排序的作用和方法。