操作系統進程調度模擬算法實現(C語言版)

目錄

1 先來先服務(FCFS)    

1.1 算法描述

1.2 實驗內容

1.3 代碼實現

2. 短進程優先(非搶佔和搶佔)算法(SPF) 

2.1 算法描述

2.2 實驗內容

2.3 代碼實現


1 先來先服務(FCFS)    

1.1 算法描述

先來先服務調度算法描述:按照進程進入的先後次序來分配處理器。先進入就緒隊列的進程優先被挑選,運行進程一旦佔有處理器將一直運行下去,直到運行結束或被阻塞,這是非搶佔式調度。

1.2 實驗內容

編寫並調試一個模擬的進程調度程序,採用 “先來先服務”調度算法對多個進程進行調度。
計算平均週轉時間和平均帶權週轉時間。

施行FCFS調度算法:  
平均進程週轉時間T = (20+30+30+35)/4 = 28.75  
平均帶權進程週轉時間W = (20/20+30/15+30/5+35/10)/4 = 3.125

1.3 代碼實現

//先來先服務
#include <stdlib.h>
#include <stdio.h>

struct pcb{   // 定義一個結構體,裏面包含的有一個進程相關的信息
	char name[10];        //進程名稱 (輸入)
	float arrivetime;     //到達時間 (輸入)
	float servicetime;    //服務時間 (輸入)
	float starttime;      //開始時間 
	float finishtime;     //結束時間 
	float zztime;        //週轉時間=finishtime-arrivetime
	float dqzztime;      //帶權週轉時間=zztime/servicetime
};   

//輸入進程信息
void input(pcb *p, int N)    //p爲pdb數組名, N爲pcb數組的元素個數 
{ 
	int i;   
    printf("\n"); 
	printf("請輸入進程的名字  到達時間  服務時間:  (例如: 進程1 0 100)\n");
	for(i=0; i<=N-1; i++)    
	{    
		printf("請輸入進程%d的信息:", i+1);  // i=0時,輸入第1個進程相關信息 
		scanf("%s", &p[i].name);		
		scanf("%f", &p[i].arrivetime);		
		scanf("%f", &p[i].servicetime);
	}    
	
} 
   
//排序: 按照進程的arrivetime(從小到大)對pcb數組中的N個進程進行排序 
void sort(pcb *p, int N)   
{     
	for(int i=0; i < N-1; i++)
	{
		for(int j=i+1; j<N; j++)  
		{
			if(p[i].arrivetime > p[j].arrivetime)   
			{    
				pcb temp;    
				temp=p[i];    
				p[i]=p[j];    
				p[j]=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].zztime = p[k].finishtime - p[k].arrivetime;    
		p[k].dqzztime = p[k].zztime / p[k].servicetime;    

     }    
} 
  
//顯示
void Print(pcb*p, int N)    
{
	int k;  
	printf("調用先來先服務算法以後進程運行的順序是: ");
	printf("%s", p[0].name); //首先運行第一個進程p[0] 
	for(k=1; k<N; k++)    
	{
		printf("-->");		
		printf("%s", p[k].name); //輸出 -->p[k].name 
	}   
	printf("\n"); 
	printf("具體進程調度信息:\n");
	printf("進程名  到達時間  服務時間  開始時間  結束時間  週轉時間  帶權週轉時間\n");
	for(k=0; k<=N-1; k++)    
	{ 
		printf("%4s", p[k].name);
		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].zztime);
		printf("%10.3f\n", p[k].dqzztime);		
     }      
}

//先來先服務算法FCFS
void FCFS(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].zztime;  
		AQttime += p[k].dqzztime;		
     }  
	Attime = Attime / N; 
	AQttime = AQttime / N;
	printf("調用先來先服務算法的平均週轉時間爲:");
	printf("%.3f\n", Attime);
	printf("調用先來先服務算法的平均帶權週轉時間爲:");
	printf("%.3f\n", AQttime);      
}  

int main( )
{
	pcb a[100]; //a爲pcb數組   a[0]~a[N-1]對象第1個進程到第N個進程的信息 
	int N;      //N爲進程數目 
	printf("\n");
	printf("\n"); 						
	printf("<<----------!!!@@@先來先服務調度算法@@@!!!---------->>");                           
	printf("\n");						
	printf("輸入進程數目:");
	scanf("%d", &N);                            
	input(a, N); //a是pcb數組名,N是實際使用數組元素個數   
	FCFS(a, N); //fcfs模擬調度 
	return 0;	
}

代碼運行結果截圖

2. 短進程優先(非搶佔和搶佔)算法(SPF) 

2.1 算法描述

短進程優先算法描述:每次選出最短的進程進行調度,調度完畢則淘汰,直到所有進程都調度完畢。

編寫並調試一個模擬的進程調度程序,採用 “短進程優先”調度算法對多個進程進行調度。
計算平均週轉時間和平均帶權週轉時間。

2.2 實驗內容

施行SPF(非搶佔式)算法:    
SPF的進程調度順序爲進程1、3、4、2,  
平均進程週轉時間T = (20+15+20+45)/4 = 25  
平均帶權進程週轉時間W = (20/20+15/5+20/10+45/15)/4 = 2.25

2.3 代碼實現

//短進程優先調度算法
#include <stdlib.h>
#include <stdio.h>

//定義一個結構體:PCB
struct pcb{   
char name[10];   
float arrivetime;   
float servicetime;   
float starttime;   
float finishtime;   
float zztime;   
float dqzztime;   
}; 
 
//***輸入進程信息,將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].name);	
		scanf("%f", &p[i].arrivetime);
		scanf("%f", &p[i].servicetime);	 
	}   
}
   
//***優先級排序***
void sort(pcb *p, int N)   
{   
	
	/*
	1、對pcb型數組中的元素進行一個簡單的排序
	找到優先級最高的進程
	並把其他進程也進行簡單排序,方便後續工作
	*/
	//排序: N次循環,每次找到從i到N-1中優先級最高的進程,放到p[i]
	for(int i=0;i<=N-1;i++)  
	{
		//循環比較剩餘的變量    //排序後:從0~N-1  arrivetime增加 , arrivetime相同時, servicetime短的優先 
		for(int 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]優先級最高,p[0].finishtime=p[0].arrivetime+p[0].servicetime
	m!=0時:p[m].finishtime=p[m-1].finishtime+p[m].servicetime
	*/
	for(int 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(int 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(int 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].zztime = p[k].finishtime - p[k].arrivetime;   
		p[k].dqzztime = p[k].zztime / p[k].servicetime;   
     }   
}  
 
//***顯示***
void Print(pcb *p, int N)   
{
	int k;      
	printf("調用最短進程優先算法以後進程運行的順序是: ");
	printf("%s",p[0].name); 
	for(k=1;k<N;k++)   
	{
		printf("-->");		
		printf("%s", p[k].name); 
	}    
	printf("\n"); 
	printf("具體進程調度信息:\n");
	printf("進程名  到達時間  服務時間  開始時間  結束時間  週轉時間  帶權週轉時間\n");
	for(k=0; k<=N-1; k++)        
	{	
		printf("%4s", p[k].name);
		//%m.nf:輸出共佔m列,其中有n位小數,如數值寬度小於m左端補空格
		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].zztime);
		printf("%10.3f\n", p[k].dqzztime);
	}         
}  
  
//***短進程優先***
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].zztime;  
		AQttime += p[k].dqzztime;		
     }  
	Attime = Attime/N; 
	AQttime = AQttime/N;
	printf("調用短進程優先算法的平均週轉時間爲:");
	printf("%.3f\n", Attime);
	printf("調用短進程優先算法的平均帶權週轉時間爲:");
	printf("%.3f\n", AQttime);      
}   

//***主函數***
int main()   
{ 
	//定義一個pcb型數組a
	pcb a[100]; 
	int N;  //進程數目                    		
	printf("\n");                          		
	printf("\n");		
	printf("<<----------******短進程優先調度算法******---------->>");	
	printf("\n");	
	printf("輸入進程數目:");
	scanf("%d", &N);                 		
	input(a, N);  		
	sjff(a, N);
	return 0; 
}   

代碼運行結果截圖

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章