进程调度算法 C C++

一、先来先服务

1.1 代码

#include <stdio.h>
#include <string.h>
double avg_TurnaroundTime;//平均周转时间
double AQTT;//平均带权周转时间
struct progress{
	char proName[80]; 
	int arriveTime;//到达时间
	int serviceTime;//服务时间
	//int flag;		//访问标志,未访问1,访问0
	int finishTime;//完成时间
	int cyclingTime;//周转时间
	double float_Wi;//带权周转时间
};

struct progress course[80];

//struct progress course[80]={{0,4},{1,3},{2,5},{3,2},{4,4}};
void health_Examine(int *courseNum)//输入合法性检查
{return;	}

void progressNum(int *courseNum)//进程数目
{int i=0;
	for(i=0; i<*courseNum;i++){
		printf("请输入第%d个进程的相应信息。\n", i+1);
		printf("请输入进程名:");
		scanf("%s", course[i].proName); 
		printf("请输入到达时间:");
		scanf("%d", &course[i].arriveTime); 
		printf("请输入服务时间:");
		scanf("%d", &course[i].serviceTime); }
	return;
}
 

void finish_Time(int *courseNum)//进程的完成时间
{int i=0;
	if(course[0].arriveTime != 0)//第一个进程的时间
	{course[0].finishTime=course[0].arriveTime + course[0].serviceTime; }
	course[0].finishTime=course[0].serviceTime;
	for(i=1; i<*courseNum; i++){
		if(course[i-1].finishTime >= course[i].arriveTime) {
			course[i].finishTime=course[i-1].finishTime + course[i].serviceTime;
		}else{
			course[i].finishTime=course[i].arriveTime + course[i].serviceTime;
		}
	}
return;
}
void cyclingTime(int *courseNum)//周转时间
{int i=0;
	for(i=0; i<*courseNum; i++)	{
		course[i].cyclingTime=course[i].finishTime - course[i].arriveTime;
	}
	return;
}
 
void float_Wi(int *courseNum)//带权周转时间
{int i=0;
	for(i=0; i<*courseNum; i++){
		course[i].float_Wi=(double)course[i].cyclingTime/course[i].serviceTime;
	}
	return;
}
 
void avgTurnaroundTime(int *courseNum)//平均周转时间
{	int i=0,sum_TurnaroundTime=0;
	for(i=0; i<*courseNum; i++){
		sum_TurnaroundTime += course[i].cyclingTime;
	}
	avg_TurnaroundTime=sum_TurnaroundTime/(*courseNum);
	return;
}
void _AQTT(int *courseNum)//平均带权周转时间
{int i=0;
	double sum_float_Wi=0;
	for(i=0; i<*courseNum; i++){
		sum_float_Wi += course[i].float_Wi;
	}
	AQTT=sum_float_Wi/(*courseNum);
	return;
}
 
void print_FIFO(int *courseNum)//输出进程相关的信息
{int i=0;
	printf("进程的相应信息。\n");
	printf("进程\t到达时间\t服务时间\t完成时间\t周转时间\t带权周转\n");//
	for(i=0; i<*courseNum;i++)	{
		//printf("第%个进程的相应信息。\n", i+1);
	printf("%s\t    %d\t\t    %d\t\t    %d\t\t   %d\t\t   %.002lf\t\t\n", course[i].proName,course[i].arriveTime,	course[i].serviceTime,course[i].finishTime,course[i].cyclingTime,course[i].float_Wi);
		//putchar('\n');
	}
	printf("平均周转时间\t平均带权周转时间\n");
	printf("   %.002lf\t\t   %.002lf\n",avg_TurnaroundTime,AQTT);
	return;	
}
int main(){
	int courseNum=5;
	printf("请输入进程数:");
	scanf("%d", &courseNum);
	progressNum(&courseNum);//
	finish_Time(&courseNum);//进程的完成时间
	cyclingTime(&courseNum);//周转时间
	float_Wi(&courseNum);//带权周转时间
	avgTurnaroundTime(&courseNum);//平均周转时间
	_AQTT(&courseNum);//平均带权周转时间
	print_FIFO(&courseNum);// 
	return 0;
}

1.2 运行截图

在这里插入图片描述

二、短进程优先

2.1 代码

#include <stdlib.h>
#include <stdio.h>
 
//定义一个结构体:PCB
typedef struct PCB{   
	char processName[10]; //进程名
	float arriveTime; //到达时间  
	float serviceTime; //服务时间
	float startTime;   //开始执行时间
	float finishTime; //结束时间
	float turnroundTime;   //周转时间
	float weightedTurnaroundTime; //带权周转时间
}pcb; 
 
//输入进程信息,将N个进程的信息写入PCB型数组
void input(pcb *p,int N)   
{
	int i;   
	printf("\n"); 
	printf("请输入进程的名字  到达时间  服务时间:  (例如: A 0 100)\n");
 
	for(i=0; i <= N-1; i++)   
	{   
		printf("请输入进程%d的信息:", i+1);
		scanf("%s", &p[i].processName);	
		scanf("%f", &p[i].arriveTime);
		scanf("%f", &p[i].serviceTime);	 
	}   
}
   
//对服务先后优先级排序
void sort(pcb *p, int N)   
{   
	
	/*
	1、对pcb型数组中的元素进行一个简单的排序
	找到优先级最高的进程
	并把其他进程也进行简单排序,方便后续工作
	*/
	//排序: N次循环,每次找到从i到N-1中优先级最高的进程,放到p[i]
	int i,j,m,n,k;
	for(i=0;i<=N-1;i++)  
	{
		//循环比较剩余的变量    //排序后:从0~N-1  arriveTime增加 , arriveTime相同时, serviceTime短的优先 
		for(j=i+1;j<N;j++) 
		{
			if(p[i].arriveTime>p[j].arriveTime || (p[i].arriveTime==p[j].arriveTime && p[i].serviceTime>p[j].serviceTime) )   
			{  
				//p[j]的优先级高于p[i],因此把p[j]放到p[i]
				pcb temp;   
				temp = p[i];   
				p[i] = p[j];   
				p[j] = temp;   
             } 
		}
	}

	//2、每个进程运行完成之后,找到当前时刻已经到达的最短进程P[0]优先级最高,
	for(m=0; m<N-1; m++)      
	{
		if(m == 0)   
			p[m].finishTime = p[m].arriveTime + p[m].serviceTime;   
		else
			p[m].finishTime = ((p[m-1].finishTime >= p[m].arriveTime)? p[m-1].finishTime: p[m].arriveTime) + p[m].serviceTime;
		//(1)找到p[m].finishTime时刻哪些进程已经到达
		int i=0;  //i统计 p[m].finishTime时刻有几个进程已经到达
		//从下一个进程p[m+1]开始寻找
		for(n = m+1; n <= N-1; n++)   
		{
			if(p[n].arriveTime <= p[m].finishTime)              
				i++;   
			else
				break;
			    /*由于在第1步已经对进程按照到达时间进行了排序
			      故:当p[n].arriveTime > p[m].finishTime时,
				      说明p[n]进程和其后面的其他进程都未到达。
				i的值为p[m].finishtime时刻已经到达的进程数目。
			   */
		}  
		//(2)找到p[m].finishTime时刻已经到达的最短进程
		float min = p[m+1].serviceTime;   //next进程服务时间为p[m+1].serviceTime (初值) 
		int next = m+1;                   //next进程为m+1 (初值) 
		//p[m+1]至p[m+i]这i个已到达进程中找到最短进程
		for(k = m+1; k < m+i; k++)       //k为m+1 ~ m+i-1   
		{   
			//min的初值是p[m+1].serviceTime, k+1为m+2 ~m+i 
			if(p[k+1].serviceTime < min)   
			{
				min = p[k+1].serviceTime;              
				next = k+1;
			}                              
		}  
		//(3)把最短进程放在p[m+1]进程处
		pcb temp;               
		temp=p[m+1];              
		p[m+1]=p[next];              
		p[next]=temp;           
	}    
} 
  
//运行
void run(pcb *p, int N)   
{
	int k; 
	//计算各进程的开始时间和结束时间
	for(k=0; k <= N-1; k++)   
     {            
		if(k==0) //第1个进程   
		{     
			p[k].startTime = p[k].arriveTime; //第1个进程到达之后即可执行   
			p[k].finishTime = p[k].startTime + p[k].serviceTime; 
		}    
		else 
		{    
			p[k].startTime = (p[k-1].finishTime >= p[k].arriveTime)? p[k-1].finishTime: p[k].arriveTime;    
			p[k].finishTime = p[k].startTime + p[k].serviceTime;
		}    
	} 
	//计算各进程的周转时间和带权周转时间
	for(k=0; k<=N-1; k++)   
	{        
		p[k].turnroundTime = p[k].finishTime - p[k].arriveTime;   
		p[k].weightedTurnaroundTime = p[k].turnroundTime / p[k].serviceTime;   
     }   
}  
 
//打印结果
void Print(pcb *p, int N)   
{
	int k;      
	printf("\n调用最短进程优先算法以后进程运行的顺序是: ");
	printf("%s",p[0].processName); 
	for(k=1;k<N;k++)   
	{
		printf("-->");		
		printf("%s", p[k].processName); 
	}    
	printf("\n"); 
	printf("具体进程调度信息:\n");
	printf("进程名  到达时间  服务时间  开始时间  结束时间  周转时间  带权周转时间\n");
	for(k=0; k<=N-1; k++)        
	{	
		printf("%4s", p[k].processName);
		printf("%10.3f", p[k].arriveTime);	
		printf("%10.3f", p[k].serviceTime);
		printf("%10.3f", p[k].startTime);
		printf("%10.3f", p[k].finishTime);
		printf("%10.3f", p[k].turnroundTime);
		printf("%10.3f\n", p[k].weightedTurnaroundTime);
	}         
}  
  
//短进程优先
void sjff(pcb *p,int N)   
{
	sort(p, N);                 
	run(p, N);         
	Print(p, N);  
	int k;
	float atTime = 0; // 平均周转时间 
	float AQTTime = 0; //平均带权周转时间 
	for(k=0; k<=N-1; k++)    
     {   
		atTime += p[k].turnroundTime;  
		AQTTime += p[k].weightedTurnaroundTime;		
     }  
	atTime = atTime/N; 
	AQTTime = AQTTime/N;
	printf("\n调用短进程优先算法的平均周转时间为:");
	printf("%.3f\n", atTime);
	printf("调用短进程优先算法的平均带权周转时间为:");
	printf("%.3f\n", AQTTime);      
}   
 

int main()   
{ 
	
	pcb a[50]; 
	int N;  //进程数目                    		
	printf("\n");                          			
	printf("\n");	
	printf("输入进程数目:");
	scanf("%d", &N);                 		
	input(a, N);  		
	sjff(a, N);
	return 0; 
}   


2.2 运行截图

在这里插入图片描述

三、时间片轮转

3.1 代码

#include<stdio.h>
#define N 50
struct PCB
{
	int pn;   //process name进程名字
	int at;   //arrival time到达时间
	int st;   //service time服务时间
	int ct;   //completion time完成时刻
	int sc;  //sign completion标志是否完成
	int st1;  //剩余服务时间  
}process[N];
 
int sjp(int n)
{
	int i,j,T;
	printf("\n请输入时间片:\n");
	scanf("%d",&T);
	for(i=1;i<=n;i++)      //收集进程信息 
	{
		process[i].sc=0;
		printf("\n%d:\n请依次输入进程的信息\n请输入pn:",i);
		scanf("%d",&process[i].pn);
		printf("请输入at:");
		scanf("%d",&process[i].at);
		printf("请输入st:");
		scanf("%d",&process[i].st);
		process[i].st1=process[i].st;
	}
	for(i=1;i<=n;i++)
	for(j=i+1;j<=n;j++)   //按照各进程到达时间升序,对进程排序 注意:稳定的排序 
	{
		if(process[j].at<process[i].at)
		{
			process[0]=process[j];
			process[j]=process[i];
			process[i]=process[0];	
		}
	}
	//for(i=1;i<=n;i++)    //检查排序是否正确
	//printf("%d\t",process[i].pn);
	
	int time=process[1].at;      //当前时间的初值 
	int flag=1;
	int sum=0;					//记录完成的进程数 
	printf("\n第几次调度进程 运行的进程pn 开始运行时间 运行时间 剩余服务时间 结束时间\n");
	int z=1;   //记录第几次调度进程 
	
        while(sum<n)
        {
	flag=0;	     //标志就绪队列中是否还有进程 
	for(i=1;i<=n;i++)    //时间片轮转法执行各进程 
	{
		if(process[i].sc==1) continue;  //已完成的进程 
		else
		 {
		 	if(process[i].st1<=T&&time>=process[i].at)//未完成的进程但是还需服务的时间少于等于一个时间片 
		 	{
		 	flag=1;
		 	time=time+process[i].st1;
		 	process[i].sc=1;
		 	process[i].ct=time;
		 	printf("%8d%12d%15d%11d%11d%11d\n",z++,process[i].pn,time-process[i].st1,process[i].st1,0,time); 
		 	process[i].st1=0;
		 	}
		 	
		 	else if(process[i].st1>T&&time>=process[i].at)//未完成的进程但其还需服务时间至少大于一个时间片 
		 	{
		 		flag=1;
		 		time=time+T;
				process[i].st1-=T;
				printf("%8d%12d%15d%11d%11d%11d\n",z++,process[i].pn,time-T,T,process[i].st1,time);
			} 
			if(process[i].sc==1) sum++;     //一个进程执行完就+1 
		}
	}
	
	if(flag==0&&sum<n)   // 还有没执行的进程,且没进入就就绪队列 
	{
	for(i=1;i<=n;i++)
	if(process[i].sc==0) {time=process[i].at;break;}
	}
    }
}
 
int main()
{
	int n;
	printf("\t\t时间片轮转调度算法\n");
	printf("请输入总进程数:\n");
	scanf("%d",&n);
	sjp(n);
	return 0;
}

3.2 运行截图

在这里插入图片描述

四、多级队列

  • 9
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值