1. 實驗目的算法
(1)加深對做業調度算法的理解;編程
(2)進行程序設計的訓練。數據結構
2.實驗要求ide
用高級語言編寫一個或多個做業調度的模擬程序。函數
單道批處理系統的做業調度程序。做業一投入運行,它就佔有計算機的一切資源直到做業完成爲止,所以調度做業時沒必要考慮它所須要的資源是否獲得知足,它所運行的時間等因素。編碼
做業調度算法:spa
1) 採用先來先服務(FCFS)調度算法,即按做業到達的前後次序進行調度。老是首先調度在系統中等待時間最長的做業。操作系統
2) 短做業優先 (SJF) 調度算法,優先調度要求運行時間最短的做業。設計
3) 響應比高者優先(HRRN)調度算法,爲每一個做業設置一個優先權(響應比),調度以前先計算各做業的優先權,優先數高者優先調度。RP (響應比)= 做業週轉時間 / 做業運行時間=1+做業等待時間/做業運行時間指針
每一個做業由一個做業控制塊JCB表示,JCB能夠包含如下信息:做業名、提交(到達)時間、所需的運行時間、所需的資源、做業狀態、鏈指針等等。
做業的狀態能夠是等待W(Wait)、運行R(Run)和完成F(Finish)三種之一。每一個做業的最初狀態都是等待W。
1、 模擬數據的生成
1. 容許用戶指定做業的個數(2-24),默認值爲5。
2. 容許用戶選擇輸入每一個做業的到達時間和所需運行時間。
3. (**)從文件中讀入以上數據。
4. (**)也容許用戶選擇經過僞隨機數指定每一個做業的到達時間(0-30)和所需運行時間(1-8)。
2、 模擬程序的功能
1. 按照模擬數據的到達時間和所需運行時間,執行FCFS, SJF和HRRN調度算法,程序計算各做業的開始執行時間,各做業的完成時間,週轉時間和帶權週轉時間(週轉係數)。
2. 動態演示每調度一次,更新如今系統時刻,處於運行狀態和等待各做業的相應信息(做業名、到達時間、所需的運行時間等)對於HRRN算法,能在每次調度時顯示各做業的響應比R狀況。
3. (**)容許用戶在模擬過程當中提交新做業。
4. (**)編寫並調度一個多道程序系統的做業調度模擬程序。 只要求做業調度算法:採用基於先來先服務的調度算法。 對於多道程序系統,要假定系統中具備的各類資源及數量、調度做業時必須考慮到每一個做業的資源要求。
3、 模擬數據結果分析
1. 對同一個模擬數據各算法的平均週轉時間,週轉係數比較。
2. (**)用曲線圖或柱形圖表示出以上數據,分析算法的優勢和缺點。
4、 實驗準備
序號 |
準備內容 |
完成狀況 |
1 |
什麼是做業? |
|
2 |
一個做業具有什麼信息? |
|
3 |
爲了方便模擬調度過程,做業使用什麼方式的數據結構存放和表示?JCB |
|
4 |
操做系統中,經常使用的做業調度算法有哪些? |
|
5 |
如何編程實現做業調度算法? |
|
6 |
模擬程序的輸入如何設計更方便、結果輸出如何呈現更好? |
|
5、 其餘要求
1. 完成報告書,內容完整,規格規範。
2. 實驗須檢查,回答實驗相關問題。
注:帶**號的條目表示選作內容。
根據指定的實驗課題,完成設計、編碼和調試工做,完成實驗報告。
能夠採用TC,也能夠選用Windows下的利用各類控件較爲方便的VB,VC等可視化環境。也能夠自主選擇其餘實驗環境。
單道FCFS算法:
#include <stdio.h> #include <stdlib.h> #include <conio.h> #define getpch(type) (type*)malloc(sizeof(type)) #define NULL 0 int n; float T1=0,T2=0; int times=0; struct jcb //做業控制塊 { char name[10]; //做業名 int reachtime; //做業到達時間 int starttime; //做業開始時間 int needtime; //做業須要運行的時間 float super; //做業的響應比 int finishtime; //做業完成時間 float cycletime; //做業週轉時間 float cltime; //做業帶權週轉時間 char state; //做業狀態 struct jcb *next; //結構體指針 }*ready=NULL,*p,*q; typedef struct jcb JCB; void inital() //創建做業控制塊隊列,先將其排成先來先服務的模式隊列 { int i; printf("\n輸入做業數:"); scanf("%d",&n); for(i=0;i<n;i++) { p=getpch(JCB); printf("輸入做業名:"); scanf("%s",p->name); getch(); p->reachtime=i; printf("做業默認到達時間:%d",i); printf("\n輸入做業需運行時間:"); scanf("%d",&p->needtime); p->state='W'; p->next=NULL; if(ready==NULL) ready=q=p; else{ q->next=p; q=p; } } } void disp(JCB* q,int m) //顯示做業運行後的週轉時間及帶權週轉時間等 { if(m==3) //顯示高響應比算法調度做業後的運行狀況 { printf("\n做業%s正在運行,估計其運行狀況:\n",q->name); printf("\n做業名 \t 做業需運行時間\n",q->name,p->needtime); printf("\n 開始運行時刻 \t 完成時刻 \t 週轉時間 \t 帶權週轉時間 \t相應比 \n"); printf(" %d \t",q->starttime); printf(" %d \t",q->finishtime); printf(" %f \t",q->cycletime); printf(" %f\t",q->cltime); printf(" %f\n",q->super); getch(); } else // 顯示先來先服務,最短做業優先算法調度後做業的運行狀況 { printf("\n做業%s正在運行,估計其運行狀況:\n",q->name); printf("\n 開始運行時刻 \t 完成時刻 \t 週轉時間 \t 帶權週轉時間 \n"); printf(" %d \t",q->starttime); printf(" %d \t",q->finishtime); printf(" %f \t",q->cycletime); printf(" %f\t",q->cltime); getch(); } } void running(JCB *p,int m) //運行做業 { if(p==ready) //先將要運行的做業從隊列中分離出來 { ready=p->next; p->next=NULL; } else { q=ready; while(q->next!=p) q=q->next; q->next=p->next; } p->starttime=times;//計算做業運行後的完成時間,週轉時間等等 p->state='R'; p->finishtime=p->starttime+p->needtime; p->cycletime=(float)(p->finishtime-p->reachtime); p->cltime=(float)(p->cycletime/p->needtime); T1+=p->cycletime; T2+=p->cltime; disp(p,m); //調用disp()函數,顯示做業運行狀況 times+=p->needtime; p->state='F'; printf("\n%s 做業已完成!\n請按任意鍵繼續...\n",p->name); free(p); //釋放運行後的做業 getch(); } void super() //計算隊列中做業的高響應比 { JCB *padv; padv=ready; do{ if(padv->state=='W'&&padv->reachtime<=times) padv->super=(float)(times-padv->reachtime+padv->needtime)/padv->needtime; padv=padv->next; }while(padv!=NULL); } void final() //最後打印做業的平均週轉時間,平均帶權週轉時間 { float s,t; t=T1/n; //計算平均週轉時間 s=T2/n; //計算平均帶權週轉時間 getch(); printf("\n\n做業已經所有完成!"); printf("\n%d個做業的平均週轉時間是:%f",n,t); printf("\n%d個做業的平均帶權週轉時間是:%f\n\n\n",n,s); } void hrn(int m) //高響應比算法 { JCB *min; int i,iden; system("cls"); //調用系統命令,清屏 inital(); for(i=0;i<n;i++) { p=min=ready; iden=1; super(); do{ if(p->state=='W'&&p->reachtime<=times) if(iden) { min=p; iden=0; } else if(p->super>min->super) min=p; p=p->next; }while(p!=NULL); if(iden) { i--; times++; if(times>1000) { printf("\nruntime is too long...error..."); getch(); } } else { running(min,m); //調用running()函數 } } final(); //調用running()函數 } void sjf(int m) // 最短做業優先算法 { JCB *min; int i,iden; system("cls"); inital(); for(i=0;i<n;i++) { p=min=ready; iden=1; do{ if(p->state=='W'&&p->reachtime<=times) if(iden) { min=p;iden=0; } else if(p->needtime<min->needtime) min=p; p=p->next; }while(p!=NULL); if(iden) { i--; times++; if(times>100){printf("\nruntime is too long...error"); getch(); } } else{ running(min,m); //調用running()函數 } } final(); //調用running()函數 } void fcfs(int m) //先來先服務算法 { int i,iden; system("cls"); inital(); for(i=0;i<n;i++) { p=ready; iden=1; do{ if(p->state=='W'&&p->reachtime<=times) iden=0; if(iden)p=p->next; }while(p!=NULL&&iden); if(iden) { i--; printf("\n沒有知足要求的進程,需等待"); times++; if(times>100){printf("\n時間過長"); getch(); } } else{ running(p,m); //調用running()函數 } } final(); //調用running()函數 } void mune() { int m; system("cls"); printf("\n\n\t\t*********************************************\t\t\n"); printf("\t\t*\t\t做業調度主菜單\t\t *\n"); printf("\t\t*********************************************\t\t\n"); printf("\n\n\t\t*********************************************\t\t"); printf("\n\t\t*\t1.先來先服務算法\t\t *"); printf("\n\t\t*\t2.最短做業優先算法\t\t *"); printf("\n\t\t*\t3.響應比高者優先算法\t\t *"); printf("\n\t\t*\t0.退出程序\t\t\t *"); printf("\n\t\t*********************************************\t\t\n"); printf("\n\t\t\t\t選擇算法:"); scanf("%d",&m); switch(m) { case 1: fcfs(m); getch(); system("cls"); mune(); break; case 2: sjf(m); getch(); system("cls"); mune(); break; case 3: hrn(m); getch(); system("cls"); mune(); break; case 0: system("cls"); break; default: printf("選擇錯誤,從新選擇."); getch(); system("cls"); mune(); } } main() //主函數 { mune(); return 0;}