先來先服務和高響應比優先排程演算法C語言實現
阿新 • • 發佈:2019-01-23
#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;
}