一、目的和要求
1. 实验目的
(1)加深对作业调度算法的理解;
(2)进行程序设计的训练。
2.实验要求
用高级语言编写一个或多个作业调度的模拟程序。
单道批处理系统的作业调度程序。作业一投入运行,它就占有计算机的一切资源直到作业完成为止,因此调度作业时不必考虑它所需要的资源是否得到满足,它所运行的时间等因素。
作业调度算法:
1) 采用先来先服务(FCFS)调度算法,即按作业到达的先后次序进行调度。总是首先调度在系统中等待时间最长的作业。
2) 短作业优先 (SJF) 调度算法,优先调度要求运行时间最短的作业。
3) 响应比高者优先(HRRN)调度算法,为每个作业设置一个优先权(响应比),调度之前先计算各作业的优先权,优先数高者优先调度。RP (响应比)= 作业周转时间 / 作业运行时间=1+作业等待时间/作业运行时间
每个作业由一个作业控制块JCB表示,JCB可以包含以下信息:作业名、提交(到达)时间、所需的运行时间、所需的资源、作业状态、链指针等等。
作业的状态可以是等待W(Wait)、运行R(Run)和完成F(Finish)三种之一。每个作业的最初状态都是等待W。
一、 模拟数据的生成
1. 允许用户指定作业的个数(2-24),默认值为5。
2. 允许用户选择输入每个作业的到达时间和所需运行时间。
3. (**)从文件中读入以上数据。
4. (**)也允许用户选择通过伪随机数指定每个作业的到达时间(0-30)和所需运行时间(1-8)。
二、 模拟程序的功能
1. 按照模拟数据的到达时间和所需运行时间,执行FCFS, SJF和HRRN调度算法,程序计算各作业的开始执行时间,各作业的完成时间,周转时间和带权周转时间(周转系数)。
2. 动态演示每调度一次,更新现在系统时刻,处于运行状态和等待各作业的相应信息(作业名、到达时间、所需的运行时间等)对于HRRN算法,能在每次调度时显示各作业的响应比R情况。
3. (**)允许用户在模拟过程中提交新作业。
4. (**)编写并调度一个多道程序系统的作业调度模拟程序。 只要求作业调度算法:采用基于先来先服务的调度算法。 对于多道程序系统,要假定系统中具有的各种资源及数量、调度作业时必须考虑到每个作业的资源要求。
三、 模拟数据结果分析
1. 对同一个模拟数据各算法的平均周转时间,周转系数比较。
2. (**)用曲线图或柱形图表示出以上数据,分析算法的优点和缺点。
四、 实验准备
| 序号 | 准备内容 | 完成情况 | 
| 1 | 什么是作业? | 
 | 
| 2 | 一个作业具备什么信息? | 
 | 
| 3 | 为了方便模拟调度过程,作业使用什么方式的数据结构存放和表示?JCB | 
 | 
| 4 | 操作系统中,常用的作业调度算法有哪些? | 
 | 
| 5 | 如何编程实现作业调度算法? | 
 | 
| 6 | 模拟程序的输入如何设计更方便、结果输出如何呈现更好? | 
 | 
五、 其他要求
1. 完成报告书,内容完整,规格规范。
2. 实验须检查,回答实验相关问题。
注:带**号的条目表示选做内容。
二、实验内容
根据指定的实验课题,完成设计、编码和调试工作,完成实验报告。
三、实验环境
可以采用TC,也可以选用Windows下的利用各种控件较为方便的VB,VC等可视化环境。也可以自主选择其他实验环境。
四、实验原理及核心算法参考程序段
单道FCFS算法:
        
#include <stdio.h> 
#include <stdlib.h>  
#include <conio.h>   
#define getpch(type) (type*)malloc(sizeof(type))  
#define NULL 0 
int n;  
float T1=0,T2=0; 
int times=0;  
struct jcb      //作业控制块 
{   
	char name[10];  //作业名   
	int reachtime;   //作业到达时间  
	int starttime;    //作业开始时间   
	int needtime;       //作业需要运行的时间  
	float super;       //作业的响应比  
	int finishtime;       //作业完成时间  
	float cycletime;       //作业周转时间   
	float cltime;           //作业带权周转时间  
	char state;            //作业状态 
    struct jcb *next;      //结构体指针 
}*ready=NULL,*p,*q;  
typedef struct jcb JCB;   
void inital() //建立作业控制块队列,先将其排成先来先服务的模式队列 
{  
	int i;  
	printf("\n输入作业数:"); 
	scanf("%d",&n); 
	for(i=0;i<n;i++)     
	{          
		p=getpch(JCB);          
		printf("输入作业名:");         
		scanf("%s",p->name);         
		getch();          
		p->reachtime=i;          
		printf("作业默认到达时间:%d",i);         
		printf("\n输入作业需运行时间:");         
		scanf("%d",&p->needtime);         
		p->state='W';         
		p->next=NULL;          
		if(ready==NULL)  ready=q=p;         
		else{              
			q->next=p;             
			q=p;             
		}     
	} 
}  
void disp(JCB* q,int m) //显示作业运行后的周转时间及带权周转时间等 
{      
	if(m==3)             //显示高响应比算法调度作业后的运行情况     
	{    
		printf("\n作业%s正在运行,估计其运行情况:\n",q->name);
		printf("\n作业名 \t 作业需运行时间\n",q->name,p->needtime);
		printf("\n 开始运行时刻 \t 完成时刻 \t 周转时间 \t 带权周转时间 \t相应比 \n");  
        printf(" %d    \t",q->starttime);     
		printf("           %d    \t",q->finishtime);    
		printf(" %f    \t",q->cycletime);    
		printf(" %f\t",q->cltime);    
		printf(" %f\n",q->super);   
		getch();     
	}      
	else      // 显示先来先服务,最短作业优先算法调度后作业的运行情况      
	{     
		printf("\n作业%s正在运行,估计其运行情况:\n",q->name);   
		printf("\n 开始运行时刻 \t 完成时刻 \t 周转时间 \t 带权周转时间 \n");     
		printf(" %d    \t",q->starttime);     
		printf("           %d    \t",q->finishtime);    
		printf(" %f    \t",q->cycletime);    
		printf(" %f\t",q->cltime);    
		getch();     
	} 
}  
void running(JCB *p,int m)      //运行作业 
{            
	if(p==ready)         //先将要运行的作业从队列中分离出来             
	{                  
		ready=p->next;                 
		p->next=NULL;             
	}             
	else             
	{                  
		q=ready;                  
		while(q->next!=p)  
			q=q->next;                 
		q->next=p->next;             
	}         
	p->starttime=times;//计算作业运行后的完成时间,周转时间等等             
	p->state='R';              
	p->finishtime=p->starttime+p->needtime;             
	p->cycletime=(float)(p->finishtime-p->reachtime);             
	p->cltime=(float)(p->cycletime/p->needtime);             
	T1+=p->cycletime;             
	T2+=p->cltime;              
	disp(p,m);        //调用disp()函数,显示作业运行情况             
	times+=p->needtime;             
	p->state='F';
	printf("\n%s 作业已完成!\n请按任意键继续...\n",p->name);             
	free(p);          //释放运行后的作业             
	getch(); 
} 
void super()          //计算队列中作业的高响应比 
{    
	JCB *padv;   
	padv=ready;  
	do{      
		if(padv->state=='W'&&padv->reachtime<=times)  
			padv->super=(float)(times-padv->reachtime+padv->needtime)/padv->needtime;      
		padv=padv->next;    
	}while(padv!=NULL); 
}  
void final()       //最后打印作业的平均周转时间,平均带权周转时间 
{      
	float s,t;     
	t=T1/n;     //计算平均周转时间
	s=T2/n;    //计算平均带权周转时间
	getch();     
	printf("\n\n作业已经全部完成!");     
	printf("\n%d个作业的平均周转时间是:%f",n,t);     
	printf("\n%d个作业的平均带权周转时间是:%f\n\n\n",n,s); 
}   
void hrn(int m)      //高响应比算法 
{    
	JCB *min;   
	int i,iden;   
	system("cls");   //调用系统命令,清屏
	inital();    
	for(i=0;i<n;i++)     
	{          
		p=min=ready;
		iden=1;         
		super();         
		do{              
			if(p->state=='W'&&p->reachtime<=times)                 
				if(iden)                     
				{                          
					min=p;
					iden=0;                     
				}                  
				else if(p->super>min->super) 
					min=p;             
				p=p->next;         
		}while(p!=NULL);
	if(iden)           
	{                
		i--;
		times++;                 
		if(times>1000)  
		{
			printf("\nruntime is too long...error...");
			getch();
		}             
	}         
	else             
	{               
		running(min,m);      //调用running()函数             
	}      
	}        
	final();           //调用running()函数 
}   
void sjf(int m)      // 最短作业优先算法 
{      
	JCB *min;     
	int i,iden;     
	system("cls");     
	inital();      
	for(i=0;i<n;i++) 
	{          
		p=min=ready;
		iden=1;         
		do{              
			if(p->state=='W'&&p->reachtime<=times)                 
				if(iden)
				{                          
					min=p;iden=0;                     
				}                  
				else if(p->needtime<min->needtime) 
					min=p;             
				p=p->next;         
		}while(p!=NULL);          
			if(iden) 
			{             
				i--;               
				times++;     
				if(times>100){printf("\nruntime is too long...error");
				getch();
				}             
			}         
			else{              
				running(min,m);      //调用running()函数         
	}     
	}  
	final();      //调用running()函数 
}   
void fcfs(int m)     //先来先服务算法 
{      
	int i,iden;     
	system("cls");     
	inital();      
	for(i=0;i<n;i++)         
	{             
		p=ready;
		iden=1;           
		do{                
			if(p->state=='W'&&p->reachtime<=times)  
				iden=0;               
			if(iden)p=p->next;              
		}while(p!=NULL&&iden);            
			if(iden)             
			{              
				i--;               
				printf("\n没有满足要求的进程,需等待");              
				times++;               
				if(times>100){printf("\n时间过长");
				getch();
				}             
			}         
			else{              
				running(p,m);    //调用running()函数          
			}       
	}      
	final();        //调用running()函数 
}   
void mune() 
{   
	int m;    
	system("cls");  
	printf("\n\n\t\t*********************************************\t\t\n"); 
	printf("\t\t*\t\t作业调度主菜单\t\t    *\n");  
	printf("\t\t*********************************************\t\t\n");
	printf("\n\n\t\t*********************************************\t\t"); 
	printf("\n\t\t*\t1.先来先服务算法\t\t    *");  
	printf("\n\t\t*\t2.最短作业优先算法\t\t    *");  
	printf("\n\t\t*\t3.响应比高者优先算法\t\t    *");  
	printf("\n\t\t*\t0.退出程序\t\t\t    *");  
	printf("\n\t\t*********************************************\t\t\n");
	printf("\n\t\t\t\t选择算法:");
	scanf("%d",&m); 
	switch(m)   
	{      
	case 1:       
		fcfs(m);       
		getch();         
		system("cls"); 
       mune();       
	   break;    
	case 2:       
		sjf(m);       
		getch();        
		system("cls");       
		mune();       
		break;    
	case 3:       
		hrn(m);       
		getch();         
		system("cls");      
		mune();       
		break;    
	case 0:       
		system("cls");      
		break;    
	default:       
		printf("选择错误,重新选择.");       
		getch();        
		system("cls");       
		mune();   
	} 
}   
main()      //主函数 
{          
	mune(); 
	return 0;
}
 
                     
                    
                 
                    
                 
         
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号