1. 程式人生 > >先來先服務和高響應比優先排程演算法C語言實現

先來先服務和高響應比優先排程演算法C語言實現

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define WAIT "Wait"//就緒狀態 
#define RUN "Run"//執行狀態 
#define FINISH "Finish"//完成狀態 
#define JOBNUMBER 5 //設定程序測試數為5   
typedef struct JCB{	
	char jobName[10];//作業名 
	int arriveTime;//到達時間 
	int runTime;//需要執行時間 
	int startTime;//開始時間 
	int endTime;//完成時間 
	int turnoverTime;//週轉時間 
	float useWeightTurnoverTime;//帶權週轉時間
	char processStatus[10];//程序狀態 	
};
static int currentTime = 0;//當前時間 
static int finishNumber = 0;//程序完成數量 
char JobArray[JOBNUMBER][10];//存放陣列名資訊的二元陣列 
float priority[JOBNUMBER];//存放程序優先順序的一元陣列 

//建立JCB
void createJCB(struct JCB* jcb){
 	freopen("input.txt","r",stdin);
 	printf("從檔案中讀入三個引數的資料:\n");
 	printf("作業號 到達時間 需要執行時間\n"); 
 	for(int i = 0; i < 5; i++){
	 	scanf("%s", &jcb[i].jobName);//作業號 
	 	scanf("%d", &jcb[i].arriveTime);//到達時間 
	 	scanf("%d", &jcb[i].runTime);//需要執行時間 
	 	jcb[i].startTime = 0;
	 	jcb[i].endTime = 0;
	 	jcb[i].turnoverTime = 0;
	 	jcb[i].useWeightTurnoverTime = 0.0;
	 	strcpy(jcb[i].processStatus, WAIT);
	 	printf("%s\t%d\t%d\n",jcb[i].jobName, jcb[i].arriveTime,jcb[i].runTime);
	}
	printf("---------------------------------------------\n");
	freopen("CON", "r", stdin);
 }
 
//列印用途
void printJob(struct JCB* jcb){
	printf("當前時間為%d\n", currentTime);
	printf("作業號 到達時間 需要執行時間 開始時間 完成時間 週轉時間 帶權週轉時間 程序狀態\n");
	for(int i = 0; i < JOBNUMBER; i++){	
		if(strcmp(jcb[i].processStatus, FINISH) == 0)//如果程序為finish狀態,這樣輸出 
			printf("%s\t%d\t%4d\t\t%d\t%d\t  %d\t  %.2f\t  %s\n", jcb[i].jobName, jcb[i].arriveTime, jcb[i].runTime, jcb[i].startTime, jcb[i].endTime, jcb[i].turnoverTime, jcb[i].useWeightTurnoverTime, jcb[i].processStatus);	
		else if(strcmp(jcb[i].processStatus, RUN) == 0)//如果程序為run狀態,這樣輸出 
			printf("%s\t%d\t%4d\t\t%d\t執行中\t  none\t  none    %s\n", jcb[i].jobName, jcb[i].arriveTime, jcb[i].runTime, jcb[i].startTime, jcb[i].processStatus);	
		else //如果程序為wait狀態,這樣輸出
			printf("%s\t%d\t%4d\t\t未執行\tnone\t  none\t  none    %s\n", jcb[i].jobName, jcb[i].arriveTime, jcb[i].runTime, jcb[i].processStatus);
	}
	printf("---------------------------------------------\n");
}

//計算平均帶權週轉時間 
float weightTurnoverTimeCount(struct JCB* jcb){
	float sum = 0.0;
	for(int i = 0; i < JOBNUMBER; i++)
		sum += jcb[i].useWeightTurnoverTime;
	return sum / JOBNUMBER;
}

//計算平均週轉時間 
float turnOverTimeCount(struct JCB* jcb){
	float sum = 0.0;
	for(int i = 0; i < JOBNUMBER; i++)
		sum += jcb[i].turnoverTime;
	return sum / JOBNUMBER;
}

//比較各個程序之間的到達時間,按升序排列 
void compare(struct JCB* jcb){
	for(int i = 0; i < JOBNUMBER; i++){
		int min = jcb[i].arriveTime, minIndex = i;
		for(int j = i + 1; j < JOBNUMBER; j++){
			if(jcb[j].arriveTime < min){
				min = jcb[j].arriveTime;
				minIndex = j;		
			}	
		}
		struct JCB temp = jcb[i];
		jcb[i] = jcb[minIndex];
		jcb[minIndex] = temp;
	}	
}

//列印程序排程順序,平均週轉時間及平均帶權週轉時間 
void printInfo(struct JCB* jcb){
	printf("1、程序排程順序為:%s -> %s -> %s -> %s -> %s\n", JobArray[0], JobArray[1], JobArray[2], JobArray[3], JobArray[4]);
	printf("2、平均週轉時間為:%.2f\n",turnOverTimeCount(jcb));
	printf("3、平均帶權週轉時間為:%.2f\n", weightTurnoverTimeCount(jcb));
	printf("------------------測試完畢 版權歸鄧欽藝所有---------\n");
}

//兩演算法共同迴圈遍歷部分 
void loop(struct JCB* jcb, int i){
	jcb[i].startTime = currentTime;
	jcb[i].endTime = jcb[i].startTime + jcb[i].runTime;
	jcb[i].turnoverTime = jcb[i].endTime - jcb[i].arriveTime;
	jcb[i].useWeightTurnoverTime = jcb[i].turnoverTime * 1.0 / jcb[i].runTime;
	strcpy(jcb[i].processStatus, RUN);
	while(true){
		if(currentTime == jcb[i].endTime){	
			strcpy(jcb[i].processStatus, FINISH);
			finishNumber++;
			if(finishNumber == JOBNUMBER)
				printJob(jcb);
			currentTime--;
			break;
		}
		else{
			printJob(jcb);
			currentTime++;	
		}	
	}
} 

//先來先服務排程演算法
void firstComeFirstServed(struct JCB* jcb){
	createJCB(jcb);
	compare(jcb);
	int i = 0; 
	//程序排程currentTime每次加1,直到程序全部被排程完成為止 
	for(; finishNumber != JOBNUMBER; currentTime++){
		if(currentTime < jcb[0].arriveTime)//當前時間小於第一個節點到來時間時,直接列印 
			printJob(jcb);
		else{
			strcpy(JobArray[i], jcb[i].jobName);
			loop(jcb, i);
			i++;
		}
	}
	printInfo(jcb);//列印程序排程順序,平均週轉時間及平均帶權週轉時間 
	currentTime = 0;//靜態變數當前時間置位
	finishNumber = 0;//靜態變數完成程序數量置位 
}

//高響應比優先排程演算法 
void highestResponseRatioNext(struct JCB* jcb){
	createJCB(jcb);
	compare(jcb);
	int i = 0, j = 0; 
	for(; finishNumber != JOBNUMBER; currentTime++){
		float maxPriority = 0.0;
		int indexPriority = 0;
		if(currentTime < jcb[0].arriveTime)//當前時間小於第一個節點到來時間時,直接列印 
			printJob(jcb);
		else{
			for(int i = 0; i < JOBNUMBER; i++){
				if(strcmp(jcb[i].processStatus, FINISH) != 0){
					int waitTime = currentTime - jcb[i].arriveTime;
				 	priority[i] = (waitTime + jcb[i].runTime) * 1.0 / jcb[i].runTime;
				 	if(priority[i] > maxPriority){
			 			maxPriority = priority[i];
			 			indexPriority = i;
			 		}
				}			 	
			}
			strcpy(JobArray[j++], jcb[indexPriority].jobName);
			loop(jcb, indexPriority);
		}
	}
	printInfo(jcb);//列印程序排程順序,平均週轉時間及平均帶權週轉時間 
	currentTime = 0;//當前時間置位
	finishNumber = 0;//完成程序數量置位 
}

//選單函式
void menu(struct JCB* jcb){
	int input; 
	while(true){
		printf("------------3114005847 鄧欽藝-----------------\n");
		printf("|        1、先來先服務排程演算法               |\n");
		printf("|        2、響應比高者優先排程演算法           |\n");
		printf("|        3、退出                             |\n");
		printf("----------------------------------------------\n");
		printf("請輸入序號以繼續程式:");
		scanf("%d", &input);
		switch(input){
			case 1:firstComeFirstServed(jcb);
				break;
			case 2:highestResponseRatioNext(jcb);
				break;
			case 3:
				exit(0);
			default:printf("輸入有誤,請重新輸入!!!\n");
				break; 
		}	
	}
} 

//主函式 
int main(){
	struct JCB jcb[JOBNUMBER];
	menu(jcb);
    system("pause");
	return 0;
}