zoukankan      html  css  js  c++  java
  • 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;
    }
    
    

    结果如下图

  • 相关阅读:
    debian7.2+nginx+mysql
    VirtualBox为虚拟OS硬盘扩容
    VirtualBox-Debian7.2-share
    linux 标准化
    linux user date
    Array方法总结
    GET和POST区别 / doGet()和doPost()的区别
    servlet错误:HTTP Status 405
    python类型转换、数值操作
    Architecture:话说科学家/工程师/设计师/商人
  • 原文地址:https://www.cnblogs.com/shallow920/p/14087937.html
Copyright © 2011-2022 走看看