OS-程序排程
阿新 • • 發佈:2020-12-05
排程演算法
-
先來先服務
-
優先順序排程(這裡是非搶佔)(第一個到達的肯定要先執行)
-
短作業優先(第一個到達的肯定要先執行)
-
時間片輪轉
時間片輪轉和先來先服務的區別就是前者也是先來先服務,但是給你三分鐘的時間片你要是幹不完一碗飯就排到最後面,等一下接著吃
實驗模擬如下
程序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("\n%d:\ninput the information of process\n 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("\ninput 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 .\n"); 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("\n"); } } 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("\ninput 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("\n processID runtime fihishtime turntime average_turntime\n");//程序名 服務時間 優先順序 完成時間 printf("%6d%10d%10d%10d%10d",pcb[i].name,pcb[i].servicetime,pcb[i].finishtime,pcb[i].turntime,pcb[i].average_turntime); printf("\n"); } } 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("\n processID runtime priority fihishtime \n");//程序名 服務時間 優先順序 完成時間 //先到達的程序第一個執行 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("\n"); 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("\n"); }//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("\n processID runtime fihishtime turntime average_turntime\n");//程序名 服務時間 優先順序 完成時間 //先到達的程序第一個執行 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("\n"); 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("\n"); }//for } void layout(int n) { int i; for(i=0;;i++) { int ch=0; printf("\n"); printf("\t\t************schedule algorithm************\n"); printf("\t\t1.FSFS\n"); printf("\t\t2.timesegment\n"); printf("\t\t3.priority\n"); printf("\t\t4.SJF\n"); printf("\t\t5.Esc\n"); printf("\t\tchoose 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!\n"); //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; }
結果如下圖