OS-进程调度

调度算法

  • 先来先服务

  • 优先级调度(这里是非抢占)(第一个到达的肯定要先执行)

  • 短作业优先(第一个到达的肯定要先执行)

  • 时间片轮转

时间片轮转和先来先服务的区别就是前者也是先来先服务,但是给你三分钟的时间片你要是干不完一碗饭就排到最后面,等一下接着吃

实验模拟如下

进程ID arrivetime servicetime priority
1 1 9 2
2 4 6 3
3 5 3 1
#include<stdio.h>
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define max 50

struct PCB
{
	int name;
	int arrivetime; //到达时间
	int servicetime; //服务时间
    int finishtime; //完成/结束时间
    int turntime; //周转时间
    int average_turntime; //带权周转时间
	int sign; //标志进程是否完成,用于后续时间片轮转中
	int remain_time; //剩余时间
	int priority;  //优先级
}pcb[max];//顺便定义进程数组pcb

void init(int n)  //初始化;这里不使用0号位置即(进程1对应下标1);0号位作为中间容器
{   
	int i;
	for(i=1;i<=n;i++)
	{
		pcb[i].arrivetime=0; 
		pcb[i].servicetime=0;
	    pcb[i].finishtime=0; 
	    pcb[i].turntime=0;
	    pcb[i].average_turntime=0;
		pcb[i].remain_time=0;
		pcb[i].sign=0;
		pcb[i].priority=0;
	}
}
void creat(int n) //创建PCB
{
	int i;
	//若n为3,则对下标1,2,3进行设置进程PCB
	for(i=1;i<=n;i++)
	{
		printf("
%d:
input the information of process
  input processID:",i);
		scanf("%d",&pcb[i].name);
		printf("  input the arrivetime:");
		scanf("%d",&pcb[i].arrivetime);
		printf("  input the servicetime:");
		scanf("%d",&pcb[i].servicetime);
		printf("  input the priority:");
		scanf("%d",&pcb[i].priority);
		pcb[i].remain_time=pcb[i].servicetime;  //初始化剩余时间为服务时间
	}
}

void FCFS(int n) //先来先服务
{
	int starttime;
	//先设置一个开始时间,有两种情况:
	//1:开始时间和第一个的进程到达时间一样,即“来了就让它执行”
	//2:如果第一进程的到达时间还没到达设置的starttime,就让它等会,等到starttime这个时间点了再让它先执行
	//其他的调度不用设置开始时间,因为第一个来的先执行
	printf("
input the start time:");
	scanf("%d",&starttime);
	if(starttime>=pcb[1].arrivetime)
	{
		pcb[1].finishtime=pcb[1].servicetime+starttime;
	}
	else
	{
		pcb[1].finishtime=pcb[1].arrivetime+pcb[1].servicetime;
	}
    int i;
	//计算剩下进程的finishtime
	for(i=2;i<=n;i++)
	{
		if(pcb[i-1].finishtime>pcb[i].arrivetime)
			pcb[i].finishtime=pcb[i-1].finishtime+pcb[i].servicetime;
		else
			pcb[i].finishtime=pcb[i].arrivetime+pcb[i].servicetime;
    }
	//计算每一个进程的周转时间和带权周转时间
    for(i=1;i<=n;i++)
        {
		pcb[i].turntime=pcb[i].finishtime-pcb[i].arrivetime;
		pcb[i].average_turntime=pcb[i].turntime/pcb[i].servicetime;
	}
}

void print_FCFS(int n)
{
	printf("process ID  arrivetime servicetime finishtime turntime  averageturntime  .
");
    int i;
	//第一个进程从下标1开始
	for(i=1;i<=n;i++)
	{
		printf("%6d%11d%12d%12d%10d%12d",pcb[i].name  ,pcb[i].arrivetime  ,pcb[i].servicetime  ,pcb[i].finishtime  ,pcb[i].turntime  ,pcb[i].average_turntime);
		printf("
");
	}

}
void time_segment(int n) //时间片轮转,在时间片轮转中只需要remain_time来表示一个进程需要的时间
{
	int i,j;
	int T;   //时间片长度
	int flag=1;   //就绪队列中是否还有进程
	int time=0;
	int sum=0;   //已经完成的进程数

	//按各进程的arrivetime进行升序排列
	for(i=1;i<=n;i++)
	for(j=i+1;j<=n;j++)  
	{
		if(pcb[j].arrivetime<pcb[i].arrivetime)
		{
			pcb[0]=pcb[j];
			pcb[j]=pcb[i];
			pcb[i]=pcb[0];	
		}
	}
	time=pcb[1].arrivetime;//时间轴初始值
	printf("
input the slicetime:");
	scanf("%d",&T);
	while(sum<n) 
	{
		flag=0;   //当前就绪队列中没有进程
		int i;
        for(i=1;i<=n;i++)
		{
			if(pcb[i].sign==1) continue; //表示该进程已完成
			else
			{
	           //没有完成的进程需要的时间大于一个时间片
				if(pcb[i].remain_time > T)
				{
					flag=1;
					time=time+T;
					pcb[i].remain_time=pcb[i].remain_time-T;

					
				}
				//没有完成的进程需要的时间小于或等于一个时间片(在这种情况下才有finishtime)
				else if(pcb[i].remain_time <= T)
				{
					flag=1;  //加入就绪队列
					time=time+pcb[i].remain_time;
					pcb[i].finishtime=time;

					pcb[i].turntime=pcb[i].finishtime - pcb[i].arrivetime;
					pcb[i].average_turntime = pcb[i].turntime/pcb[i].servicetime;

                    pcb[i].sign=1;//进程完成标志sign,即退出就绪队列
		 	        pcb[i].remain_time=0;//及时归零
				}
				
				if(pcb[i].sign==1) sum++;
			}

		}//for


		if(flag==0&&sum<n)   // 还有没执行的进程,且没进入就就绪队列 
		{
        	int i;
			for(i=1;i<=n;i++)
			if(pcb[i].sign==0) {time=pcb[i].arrivetime;break;}//如果有没执行的进程,时间轴置放到它的到达时间上
		}


	}//while

}
void print_time(int n)
{   
	int i;
	for(i=1;i<=n;i++)
	{
		printf("
 processID runtime fihishtime turntime average_turntime
");//进程名   服务时间   优先级  完成时间
		printf("%6d%10d%10d%10d%10d",pcb[i].name,pcb[i].servicetime,pcb[i].finishtime,pcb[i].turntime,pcb[i].average_turntime);
		printf("
");
	}
}

void Priority(int n)
{
	int i,j;
	int time = pcb[1].arrivetime;
	//按各进程的arrivetime进行升序排列,最早到达的进程先执行
	for(i=1;i<=n;i++)
	for(j=i+1;j<=n;j++)  
	{
		if(pcb[j].arrivetime < pcb[i].arrivetime)
		{
			pcb[0]=pcb[j];
			pcb[j]=pcb[i];
			pcb[i]=pcb[0];	
		}
	}
	printf("
 processID runtime priority fihishtime 
");//进程名   服务时间   优先级  完成时间
	//先到达的进程第一个执行
	if(i=1)
	{
		pcb[i].finishtime=pcb[i].arrivetime + pcb[i].servicetime;
		time =pcb[i].arrivetime + pcb[i].servicetime;
		printf("%6d%10d%10d%10d",pcb[i].name,pcb[i].servicetime,pcb[i].priority,pcb[i].finishtime);
		printf("
");
		i++;
	}

	//按各进程的priority进行降序排列,优先级最高的进程先执行
	for(i=2;i<=n;i++)
	for(j=i+1;j<=n;j++)  
	{
		if(pcb[j].priority > pcb[i].priority)
		{
			pcb[0]=pcb[j];
			pcb[j]=pcb[i];
			pcb[i]=pcb[0];	
		}
	}
	
	for(i=2;i<=n;i++)
	{
		time = time + pcb[i].servicetime;
		pcb[i].finishtime = time;
		printf("%6d%10d%10d%10d",pcb[i].name,pcb[i].servicetime,pcb[i].priority,pcb[i].finishtime);
		printf("
");
	}//for

}//void

void SJF(int n)//短作业优先并输入进程个数
{
	int i,j;
	int time = pcb[1].arrivetime;//时间轴以第一个进程的到达时间为起点
	//按各进程的arrivetime进行升序排列,但最早到达的进程毋庸置疑先执行
	//只要有前后关系就有双重for循环
	//目的求出第一个到达的进程在pcb[1]里
	for(i=1;i<=n;i++)
	for(j=i+1;j<=n;j++)  
	{
		if(pcb[j].arrivetime < pcb[i].arrivetime)
		{
			pcb[0]=pcb[j];
			pcb[j]=pcb[i];
			pcb[i]=pcb[0];	
		}
	}

	printf("
 processID runtime fihishtime turntime average_turntime
");//进程名   服务时间   优先级  完成时间
	//先到达的进程第一个执行
	if(i=1)
	{
		pcb[i].finishtime=pcb[i].arrivetime + pcb[i].servicetime;
		time =pcb[i].arrivetime + pcb[i].servicetime;
		pcb[i].turntime=pcb[i].finishtime - pcb[i].arrivetime;
		pcb[i].average_turntime = pcb[i].turntime/pcb[i].servicetime;
		printf("%6d%10d%10d%10d%10d",pcb[i].name,pcb[i].servicetime,pcb[i].finishtime,pcb[i].turntime,pcb[i].average_turntime);
		printf("
");
		i++;
	}
	//按各进程的服务时间进行升序排列,servicetime越短的进程先执行
	for(i=2;i<=n;i++)
	for(j=i+1;j<=n;j++)  
	{
		if(pcb[j].servicetime < pcb[i].servicetime)
		{
			pcb[0]=pcb[j];
			pcb[j]=pcb[i];
			pcb[i]=pcb[0];	
		}
	}
	//对排序后的进程序列进行计算
	for(i=2;i<=n;i++)
	{
		time = time + pcb[i].servicetime;
		pcb[i].finishtime = time;
		pcb[i].turntime=pcb[i].finishtime - pcb[i].arrivetime;
		pcb[i].average_turntime = pcb[i].turntime/pcb[i].servicetime;
		printf("%6d%10d%10d%10d%10d",pcb[i].name,pcb[i].servicetime,pcb[i].finishtime,pcb[i].turntime,pcb[i].average_turntime);
		printf("
");
	}//for
}

				
void layout(int n)
{
	int i;
	for(i=0;;i++)
	{
		int ch=0;
		printf("
");
		printf("		************schedule algorithm************
");
		printf("		1.FSFS
");
		printf("		2.timesegment
");
		printf("		3.priority
");
		printf("		4.SJF
");
		printf("		5.Esc
");
		printf("		choose the algorithm:");
		scanf("%10d",&ch);
		switch(ch)
		{
			case 1:
		    		FCFS(n);
		    		print_FCFS(n); break;
			case 2:
		    		time_segment(n);
		   			print_time(n); break;
			case 3:
		    		Priority(n); break;//print代码段已内置
			case 4:
					SJF(n);break;//print代码段已内置
			case 5:
					exit(0);
			default:printf("enter error data!
");
			//P:int类型的变量,case后面不要加''
		}
	}
}

int main()
{ 
	int n;
	printf("Input the number of process: ");
	scanf("%d",&n);
	init(n);//初始化pcb数组为零
	creat(n);//根据输入信息更改pcb数组
	layout(n);
	return 0;
}

结果如下图

原文地址:https://www.cnblogs.com/shallow920/p/14087937.html