c語言模擬短作業優先排程演算法和時間片轉輪排程演算法
阿新 • • 發佈:2018-12-26
陣列模擬短作業,隊咧模擬時間片轉輪,註釋很清楚,就不贅述
程式碼:
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<time.h> #include<set> #include<unistd.h> #define R "RUN" //執行中 #define F "FINISH" //已完成 #define W "WAITE" //等待中 #define T "TAKEN" //未提交 #define MAX 5 struct PCB{ char Name[10];//程序名 int Arrive;//到達時間 int Need;//需要執行時間 int Start;//開始時間 int End;//完成時間 int Turnover;//週轉時間 int Priority;//優先順序 int CpuTime;//所用cpu時間 float UseWeightTurnover;//帶權週轉時間 char Status[10];//程序狀態 }; int CurrentTime;//當前時間 int finish;//已完成數量 char c; //演算法選擇 int visit[MAX]; //標記是否存在佇列 //建立PCB void CreatePCB(struct PCB* pcb){ int fd_stdin=dup(fileno(stdin)); freopen("d:\\input.txt","r",stdin); printf("從檔案中讀入四個引數的資料:\n"); printf("作業號 優先順序 到達時間 需要執行時間\n"); for(int i= 0;i<MAX;i++){ scanf("%s",&pcb[i].Name);//程序名 scanf("%d",&pcb[i].Priority);//優先順序 scanf("%d",&pcb[i].Arrive);//到達時間 scanf("%d",&pcb[i].Need);//需要執行時間 pcb[i].Start=-1; pcb[i].End=-1; pcb[i].Turnover=0; pcb[i].UseWeightTurnover=0.0; pcb[i].CpuTime=0; strcpy(pcb[i].Status, T); printf("%s\t%2d\t%2d\t%5d\n",pcb[i].Name, pcb[i].Priority,pcb[i].Arrive,pcb[i].Need); } fclose(stdin); fdopen(fd_stdin,"r"); printf("---------------------------------------------\n"); } typedef struct Node { int data; /*資料域*/ struct Node *next; /*指標域*/ }Node; typedef struct { Node *front; Node *rear; }Queue; void InitQueue(Queue *q) { /* 將Q初始化為一個空的鏈佇列 */ q->front=(Node *)malloc(sizeof(Node)); if(q->front!=NULL){ q->rear=q->front; q->front->next=NULL; } } /*入隊操作。*/ void Enqueue(Queue *q,int x) { /* 將資料元素x插入到佇列Q中 */ Node *NewNode; NewNode=(Node *)malloc(sizeof(Node)); if(NewNode!=NULL){ NewNode->data=x; NewNode->next=NULL; q->rear->next=NewNode; q->rear=NewNode; } } /*出隊操作。*/ int Dequeue(Queue *q) { /* 將佇列Q的隊頭元素出隊,並存放到x所指的儲存空間中 */ Node *p; int x; p=q->front->next; q->front->next=p->next; if(q->rear==p) q->rear=q->front; x=p->data; free(p); return x; } //列印 void Display(struct PCB* pcb){ int i; printf("當前時間為%d\n", CurrentTime); printf("程序名 優先順序 到達時間 需要執行時間 已用cpu時間 開始時間 完成時間 程序狀態\n"); for(i=0;i<MAX;i++){ printf("%s\t%d\t%3d\t%4d\t\t%d\t%4d\t%6d\t %s\n", pcb[i].Name,pcb[i].Priority,pcb[i].Arrive, pcb[i].Need,pcb[i].CpuTime,pcb[i].Start, pcb[i].End, pcb[i].Status); } printf("--------------------------------------------------------------------------\n"); } //程序狀態檢測與修改 void StatusConfirm(struct PCB* pcb){ int i; for(i=0;i<MAX;i++){ //到達時間等於當前時間則狀態變為等待中 if(CurrentTime>=pcb[i].Arrive&&strcmp(pcb[i].Status,T)==0){ strcpy(pcb[i].Status,W); } if(pcb[i].CpuTime==pcb[i].Need&&strcmp(pcb[i].Status,W)==0){ finish++; strcpy(pcb[i].Status,F); pcb[i].End=CurrentTime; pcb[i].Turnover=pcb[i].End-pcb[i].Arrive; pcb[i].UseWeightTurnover=pcb[i].Turnover*1.0/pcb[i].Need; } } } //取就緒佇列中執行時間最短的程序下標 int ShortIndex(struct PCB* pcb){ int i; int min; int temp; min=100; temp=-1; StatusConfirm(pcb);//更新程序狀態 for(i=0;i<MAX;i++){ if(strcmp(pcb[i].Status,W)==0){ if(pcb[i].Need< min){ //有更小的執行時間則更新 min=pcb[i].Need; temp=i; } } } return temp; } //比較各個程序之間的到達時間,按升序排列 void Sort(struct PCB* pcb){ int i; int j; int min; int minIndex; for(i=0;i<MAX;i++){ min=pcb[i].Arrive; minIndex=i; for(j=i+1;j<MAX;j++){ if(pcb[j].Arrive<min){ min=pcb[j].Arrive; minIndex = j; } } struct PCB temp=pcb[i]; pcb[i]=pcb[minIndex]; pcb[minIndex]=temp; } } //短作業優先 void ShortRuntime(struct PCB* pcb) { Sort(pcb); int index; int first; first=pcb[0].Arrive; for(index=0,finish=0;finish!=MAX;CurrentTime++){ //程序排程位currentTime每次加1,直到程序全部被排程完成為止 StatusConfirm(pcb); if(CurrentTime<first||ShortIndex(pcb)==-1) {//最快到達的程序還未到達或就緒佇列中無程序 Display(pcb); } else{ index=ShortIndex(pcb);//取執行時間最短程序 pcb[index].Start=CurrentTime; //更新開始執行時間 strcpy(pcb[index].Status,R); //更新程序狀態為執行中 while(true){//執行此程序 StatusConfirm(pcb); if(pcb[index].Need==pcb[index].CpuTime){ //若所用的cpu時間等於所需執行時間 strcpy(pcb[index].Status,F); //程序狀態變為已完成 finish++; break; } else{ Display(pcb); CurrentTime++; } pcb[index].CpuTime++;//已用時間片+1 StatusConfirm(pcb); }; pcb[index].End=CurrentTime; //更新完成時間 pcb[index].Turnover=pcb[index].End-pcb[index].Arrive; //計算週轉時間 pcb[index].UseWeightTurnover= pcb[index].Turnover*1.0/pcb[index].Need;//計算帶權週轉時間 strcpy(pcb[index].Status,F); CurrentTime--; } } Display(pcb); } //時間片轉輪法 void HighPriority(struct PCB* pcb) { Queue LQ; InitQueue(&LQ);//建立佇列 Sort(pcb);//按到達時間排列 int index; int first; int j; int i; first=pcb[0].Arrive; memset(visit,0,sizeof(visit));//標記陣列置零 for(index=0,finish=0;finish!=MAX;CurrentTime++){ //程序排程位currentTime每次加1,直到程序全部被排程完成為止 StatusConfirm(pcb); //getchar(); if(CurrentTime<first||ShortIndex(pcb)==-1) {//最快到達的程序未到達或就緒佇列無程序 Display(pcb); } else{ if(CurrentTime==first){ Enqueue(&LQ,0); visit[0]=1; } for(i=0,j=index+1;i<MAX;i++,j++){//將提交的程序入隊 if(j==MAX){ j=0; } if(!visit[j]&&strcmp(pcb[j].Status,W)==0){ Enqueue(&LQ,j); visit[j]=1;//已存在佇列 } } index=Dequeue(&LQ);//取隊頭 visit[index]=0;//不存在佇列中 if(pcb[index].Start==-1){//更新程序開始執行時間 pcb[index].Start=CurrentTime; } strcpy(pcb[index].Status,R);//程序狀態為執行中 Display(pcb); pcb[index].CpuTime++;//當前程序所用cpu時間增加 if(pcb[index].CpuTime==pcb[index].Need){//若所用cpu時間已達到所需執行時間 strcpy(pcb[index].Status,F); pcb[index].End=CurrentTime+1;// 更新完成時間 pcb[index].Turnover=pcb[index].End-pcb[index].Arrive; //計算週轉時間 pcb[index].UseWeightTurnover= pcb[index].Turnover*1.0/pcb[index].Need;//計算帶權週轉時間 finish++; } else{ strcpy(pcb[index].Status,W);//時間片用完程序重新變為等待狀態 } } } Display(pcb); } //計算平均帶權週轉時間 float WeightTurnoverTimeCount(struct PCB* pcb){ float sum = 0.0; for(int i = 0; i <MAX; i++){ sum += pcb[i].UseWeightTurnover; } return sum /MAX; } //計算平均週轉時間 float TurnOverTimeCount(struct PCB* pcb){ float sum = 0.0; for(int i = 0; i <MAX; i++){ sum += pcb[i].Turnover; } return sum /MAX; } //開始程序排程 void Start(struct PCB* pcb){ int i; printf("請選擇程序排程演算法:\n1、短作業優先排程演算法。2、時間片轉輪排程演算法。\n\n"); scanf("%c",&c); switch(c){ case '1':ShortRuntime(pcb);break; case '2':HighPriority(pcb);break; default:break; } printf("程序名 週轉時間 帶權週轉時間\n"); for(i=0;i<MAX;i++){ printf("%s\t%d\t%.2f\n", pcb[i].Name,pcb[i].Turnover,pcb[i].UseWeightTurnover); } printf("---------------------------------------------\n"); printf("平均週轉時間為:%.2f\n",TurnOverTimeCount(pcb)); printf("平均帶權週轉時間為:%.2f\n", WeightTurnoverTimeCount(pcb)); } //主函式 int main(){ struct PCB pcb[MAX]; CreatePCB(pcb); Start(pcb); return 0; }