操作系统 第四次实验 CPU调度算法模拟实验

目标:
• 1. 复习CPU调度的四种基本调度算法
• 2.复习平均等待时间以及平均周转时间
• 3. 通过编程模拟CPU调度的过程,深化对CPU的四种基本调度算法的理解

基本调度算法
• FCFS(先进先出算法)
• SJF(短作业优先算法)
• 优先级调度算法
• RR(时间片轮转调度算法)

等待时间和周转时间
• 等待时间
– 进程在等待队列中的时间总和
• 周转时间
– 进程从提交到进程完成的时间总和

实验内容
• 分别使用FCFS、 SJF(非抢占)、优先级调度(非抢占)、 RR四种调度算法来模拟CPU调度的过程。(Linux、 Windows下皆可,语言不限)
• 输入:存储需要调度的作业信息的job.txt文档
• 输出:每个作业的编号、作业开始执行时间、作业结束时间以及该调度算法的平均等待时间、平均周转时间
• 选作: SJF(抢占)、优先级调度(抢占)

说明:
• 1. job.txt说明:

第一行:作业数 轮转片大小
第二行以后:作业编号 到达时间 执行时间 优先级
• 2. 输出说明:
FCFS: 作业编号 开始执行时间 结束时间
…… …… ……
Average waiting time: 平均等待时间
Time for Average Turnaround : 平均周转时间
SJF(非抢占): 作业编号 开始执行时间 结束时间
…… …… ……
Average waiting time: 平均等待时间
Time for Average Turnaround : 平均周转时间
……

代码:

#include<stdio.h>
#include<queue>
#include<iostream>
using namespace std;
int pnum;
int ptime;
int index[255];
int time1[255];
int use_time[255];
int level[255];
void FCFS()
{
	int wait_time[255];
	int turn_time[255];
	int nowtime=0;
	printf("FCFS: \n作业编号 开始执行时间  结束时间   \n");
	for(int i=0;i<pnum;i++)
	{
		printf("%d ",index[i]);
		/*开始运行*/
		if(time1[i]>=nowtime)  //到达时间大于现在时间 ,作业晚到wait 
		{
			printf("%d ",time1[i]);
			nowtime=time1[i];
			wait_time[i]=0; //作业没有等待 
		}
		else//到达时间小于现在时间 ,作业早到 
		{
			printf("%d ",nowtime);
			wait_time[i]=nowtime-time1[i];  
		}
		/*结束时间*/
		printf("%d ",nowtime+use_time[i]);
		nowtime+=use_time[i];
		turn_time[i]=nowtime-time1[i];  //结束时间-到达时间 
		printf("\n");
	}
	
	float all_wait_time=0;
	float all_turn_time=0;
	for(int i=0;i<pnum;i++)
	{
		all_wait_time+=wait_time[i];
		all_turn_time+=turn_time[i];
	}
	printf("Average waiting time:%f\n",all_wait_time/pnum);
	printf("Time for Average Turnaround : %f\n",all_turn_time/pnum);	
}
int flag[255];  //find_min 表示以读取 
int check()//检查是否完成 完成返回0 
{
	int end=0;
	for(int i=0;i<pnum;i++)
		if(flag[i]==0)
			end=1;
	return end;	
}
int find_min(int have_in)
{
	int next=999;
	int min=999;
	for(int i=0;i<have_in;i++)
	{
		if(flag[i]==0 && use_time[i]<min)
		{
			min=use_time[i];
			next=i;
		}
	}
	return next;
}
void SJF()
{
	int have_in=1;
	int wait_time[255];
	int turn_time[255];
	int nowtime=0;
	float all_wait_time=0;
	float all_turn_time=0;
	for(int i=0;i<255;i++)
		flag[i]=0;
	printf("SJF(非抢占):\n 作业编号 开始执行时间  结束时间\n");
	int i=0;
	while(1)
	{
		if(have_in==0)  //第一个
		{
			printf("%d %d %d\n",index[0],time1[0],use_time[0]);
			nowtime=time1[i]+use_time[0];	
			wait_time[0]=0;
			turn_time[0]=use_time[0];
			flag[0]=1;	//已经运行		
		} 
		for(int j=have_in;j<pnum;j++)  //查找运行一个作业期间进入队列的其他队列 
		{
			if(nowtime>=time1[j]&&flag[j]==0)  //目前时间>=到达时间  作业到达
				have_in++; 
		}
		
		int next=find_min(have_in);
 		if(check()==0)  //结束判断 
 			break;
		if(next==999)//目前没有新的作业进入 
		{
			next=have_in; //直接取下一个 
			have_in++;	
			nowtime=time1[next];   //现在时间跳到下一个进程进入时间		
		}
	
		printf("%d ",index[next]);
		printf("%d ",nowtime);
		printf("%d \n",nowtime+use_time[next]);
		wait_time[next]=nowtime-time1[next];
		nowtime+=use_time[next];
		turn_time[next]=nowtime-time1[next];
		flag[next]=1;
				
	}
	for(int i=0;i<pnum;i++)
	{
		all_wait_time+=wait_time[i];
		all_turn_time+=turn_time[i];
	}
	printf("Average waiting time:%f\n",all_wait_time/pnum);
	printf("Time for Average Turnaround : %f\n",all_turn_time/pnum);
	
}

int find_max(int have_in)
{
	int next=999;
	int min=999;
	for(int i=0;i<have_in;i++)
	{
		if(flag[i]==0 && level[i]<min)
		{
			min=level[i];
			next=i;
		}
	}
	return next;
}
void Power()
{
	int have_in=1;
	int wait_time[255];
	int turn_time[255];
	int nowtime=0;
	float all_wait_time=0;
	float all_turn_time=0;
	for(int i=0;i<255;i++)
		flag[i]=0;
	printf("优先级调度(非抢占):\n 作业编号 开始执行时间  结束时间\n");
	while(1)
	{
		if(have_in==0)  //第一个
		{
			printf("%d ",index[0]);
			printf("%d ",time1[0]);
			printf("%d \n",use_time[0]);
			nowtime=time1[0]+use_time[0];	
			wait_time[0]=0;
			turn_time[0]=use_time[0];
			flag[0]=1;	//已经运行		
		} 
		for(int j=have_in;j<pnum;j++)  //查找运行一个作业期间进入队列的其他队列 
		{
			if(nowtime>=time1[j]&&flag[j]==0)  //目前时间>=到达时间  作业到达
				have_in++; 
		}
		
		int next=find_max(have_in);
		if(check()==0)  //结束判断 
 			break;
		if(next==999)//目前没有新的作业进入 
		{
			next=have_in; //直接取下一个 
			have_in++;	
			nowtime=time1[next];   //现在时间跳到下一个进程进入时间		
		}	
		printf("%d ",index[next]);
		printf("%d ",nowtime);
		printf("%d \n",nowtime+use_time[next]);
		wait_time[next]=nowtime-time1[next];
		nowtime+=use_time[next];
		turn_time[next]=nowtime-time1[next];
		flag[next]=1;
				
	}
	for(int i=0;i<pnum;i++)
	{
		all_wait_time+=wait_time[i];
		all_turn_time+=turn_time[i];
	}
	printf("Average waiting time:%f\n",all_wait_time/pnum);
	printf("Time for Average Turnaround : %f\n",all_turn_time/pnum);
}

void RR()
{
	   queue<int> p;  //创建队列
	   p.push(0);
	   int nowtime=time1[0];//调整现在时间 
	   int have_use_time[255];//已经工作时间
	   int start_time[255];//开始工作时间
	   int end_time[255];//结束工作时间 
	   float wait_time[255];
	   float turn_time[255];
	   int have_in=1; //已经进入 
	   for(int i=0;i<255;i++)
	   {
	   		flag[i]=0;
	   		have_use_time[i]=0;
	   		start_time[i]=0;
	   		end_time[i]=0;
	   		wait_time[i]=0;
	   		turn_time[i]=0;
	   }
	   while(check()==1) 
	   {
	   		
	   		/*从队列中取出一个作业*/
	   		int i=p.front();
	   		p.pop();
	   		if(have_use_time[i]==0)//运行时间为零,第一次进入
				start_time[i]=nowtime;   	
			
			if(have_use_time[i]+ptime>=use_time[i])
			{
				nowtime+=use_time[i]-have_use_time[i];
				flag[i]=1;
				have_use_time[i]=use_time[i]; 
				end_time[i]=nowtime;	
			}
			else
			{
				nowtime+=ptime;	
				have_use_time[i]+=ptime;
			}
			for(int j=have_in;j<pnum;j++)
			{
				if(nowtime>=time1[j]&&flag[j]==0)//已经进入 
				{
					
					have_in++;
					p.push(j);
				}
			}
			
			if(have_use_time[i]!=use_time[i])
				p.push(i);
				
			if(p.empty() && check())//队列空 但未完成 
			{
				nowtime=time1[have_in];
				p.push(have_in);
				have_in++;
			}				
	   }
	   float all_wait_time=0;
	   float all_turn_time=0;
	   
	   for(int i=0;i<pnum;i++)
	   {
	   		wait_time[i]=end_time[i]-time1[i]-use_time[i];//等待时间=结束时间-到达时间-工作时间
			turn_time[i]=end_time[i]-time1[i]; 
			printf("%d %d %d\n",index[i],start_time[i],end_time[i]);
			
			all_wait_time+=wait_time[i];
			all_turn_time+=turn_time[i];
	   }
	printf("Average waiting time:%f\n",all_wait_time/pnum);
	printf("Time for Average Turnaround : %f\n",all_turn_time/pnum);
} 

int main()
{
	FILE *fp=NULL;
	
	fp=fopen("job.txt","r");
	fscanf(fp,"%d",&pnum);//作业量 
	fscanf(fp,"%d",&ptime);//时间片 
	
	for(int i=0;i<pnum;i++)
	{
		fscanf(fp,"%d",&index[i]);//标号 
		fscanf(fp,"%d",&time1[i]);//到达时间 
		fscanf(fp,"%d",&use_time[i]);//所需时间 
		fscanf(fp,"%d",&level[i]);//优先级			
	}
	fclose(fp);
	printf("%d %d\n",pnum,ptime);
	for(int i=0;i<pnum;i++)
	{
		printf("%d %d %d %d\n",index[i],time1[i],use_time[i],level[i]);
	}
	FCFS();
	SJF();
	Power();
	RR(); 
}
上一篇:【前端常用小知识】js的防抖与节流概念


下一篇:报时助手