實驗二做業調度模擬程序算法
1. 實驗目的編程
(1)加深對做業調度算法的理解;數組
(2)進行程序設計的訓練。數據結構
2.實驗要求函數
用高級語言編寫一個或多個做業調度的模擬程序。性能
單道批處理系統的做業調度程序。做業一投入運行,它就佔有計算機的一切資源直到做業完成爲止,所以調度做業時沒必要考慮它所須要的資源是否獲得知足,它所運行的時間等因素。編碼
做業調度算法: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. (**)用曲線圖或柱形圖表示出以上數據,分析算法的優勢和缺點。
1、 實驗準備
序號 |
準備內容 |
完成狀況 |
1 |
什麼是做業? |
每一個用戶請求計算機的一個計算任務叫作一個做業。 |
2 |
一個做業具有什麼信息? |
做業調度要考慮2個因素:一、接納多少個做業。這個取決於多道程序度(Degree of Multiprogamming),即同時容許多少個做業在內存中運行。太多影響系統性能,過低下降了系統的資源利用率和吞吐率。二、接納哪些做業。這個取決於調度算法,調度的算法不少,常見的就FCFS(先來先服務)、短做業優先調度算法、高優先權調度算法和基於時間片輪轉的算法。 |
3 |
爲了方便模擬調度過程,做業使用什麼方式的數據結構存放和表示?JCB |
先來先服務, |
4 |
操做系統中,經常使用的做業調度算法有哪些? |
先來先服務(FCFS, First Come First Serve)是最簡單的調度算法,按前後順序進行調度。 輪轉法(Round Robin)是讓每一個進程在就緒隊列中的等待時間與享受服務的時間成正比例。 多級反饋隊列算法(Round Robin with Multiple Feedback)是輪轉算法和優先級算法的綜合和發展。 |
5 |
如何編程實現做業調度算法? |
1 、在單位時間內運行儘量多的做業。 2 、使處理機保持忙碌的狀態。 3 、使 I / O 設備得以充分利用。 4 、對全部做業公平合理。
|
6 |
模擬程序的輸入如何設計更方便、結果輸出如何呈現更好? |
用數組存儲 |
2、 其餘要求
1. 完成報告書,內容完整,規格規範。
2. 實驗須檢查,回答實驗相關問題。
注:帶**號的條目表示選作內容。
根據指定的實驗課題,完成設計、編碼和調試工做,完成實驗報告。
能夠採用TC,也能夠選用Windows下的利用各類控件較爲方便的VB,VC等可視化環境。也能夠自主選擇其餘實驗環境。
#include<stdio.h> #include<stdlib.h> #include <IOSTREAM> #include<conio.h> #include<string.h> #include<stdio.h> #include<math.h> #include <numeric> #include <cstdlib> #include <numeric> #include<time.h> #define MAX 100 typedef struct process_jcb{ char name; int arrivetime; int waittime; int finishtime; int needtime; int roundtime; float Talltime; int starttime; int id; struct process_jcb *link; }JCB; JCB *p,*q,*head=NULL; int n;//錄入做業個數 struct process_jcb a[100]; JCB inital(struct process_jcb a[],int n); void print(struct process_jcb a[],int n); void Fcfs(struct process_jcb a[],int n); void SJFS(struct process_jcb a[],int n); void ReadFile(); struct process_jcb *sortarrivetime(struct process_jcb a[],int n); struct process_jcb *sortservetime(struct process_jcb a[],int n); //按服務時間進行冒泡排序 struct process_jcb *sortservetime(struct process_jcb a[],int n) { int i,j; struct process_jcb t; int flag; for(i=1;i<n;i++) { flag=0; for(j=1;j<n-i;j++) { if(a[j].needtime>a[j+1].needtime) //將到達時間短的交換到前邊 { t=a[j]; a[j]=a[j+1]; a[j+1]=t; flag=1;//交換 } } if(flag==0)//若是一趟排序中沒發生任何交換,則排序結束 { break; } } return a; //返回排序後進程數組 } struct process_jcb *sortarrivetime(struct process_jcb a[],int n)//對到達時間進行排序 { int i,j; struct process_jcb t; int flag; for(i=1;i<n;i++) { flag=0; for(j=0;j<n-i;j++) { if(a[j].arrivetime>a[j+1].arrivetime) { t=a[j]; a[j]=a[j+1]; a[j+1]=t; flag=1; } } if(flag==0) break; } return a; } void Fcfs(struct process_jcb a[],int n) { int i; a[0].finishtime=a[0].arrivetime+a[0].needtime; a[0].roundtime=a[0].finishtime-a[0].arrivetime; a[0].Talltime=a[0].roundtime/a[0].needtime; for(i=1;i<n;i++) { if(a[i].arrivetime<a[i-1].finishtime) { a[i].finishtime=a[i-1].finishtime+a[i].needtime; a[i].roundtime=a[i].finishtime-a[i].arrivetime; a[i].Talltime=a[i].roundtime/a[i].needtime; } else { a[i].finishtime=a[i].arrivetime+a[i].needtime; a[i].roundtime=a[i].finishtime+a[i].arrivetime; a[i].Talltime=a[i].roundtime/a[i].needtime; } printf("\n--------------------------\n"); } printf(" \n 先來先服務算法 \n"); print(a,n); } void print(struct process_jcb a[],int n) { int i; printf("\n--------------------------\n"); printf(" 到達時間:| 服務時間:| 完成時間:| 週轉時間:|帶權週轉時間\n "); for(i=0;i<n;i++) { printf("\n--------------------------\n"); printf("做業%d:",i+1); printf(" %.2d % .2d % .2d % .2d % .2f\n",a[i].arrivetime,a[i].needtime,a[i].finishtime,a[i].roundtime,a[i].Talltime); } printf("\n"); } void main() { int j; int choice; printf(" \n\n\n\n ============================================= \n"); printf(" 做業調度模擬 \n"); printf(" ============================================= "); printf("\n 1.先到先服務算法\n"); printf(" 2.最短做業優先算法\n"); printf(" ============================================= \n"); scanf("%d",&j); getchar(); printf("\n\n\n 1.讀入D盤中READFILE.txt的數據?(是請按1)\n"); printf(" 2.讀入隨機數據數據?(是請按2)\n"); printf(" 3.手動輸入數據?(是請按3)\n"); scanf("%d",&choice); getchar(); if(choice==1){//文件讀取的方式 int i=0; FILE *fp; //定義文件指針 fp=fopen("D:\\readfile.txt","r"); //打開文件 if(fp==NULL) { printf("File open error !\n"); exit(0); } printf("\n id 做業到達時間 做業運行所須要時間\n"); while(!feof(fp)) { fscanf(fp,"%d%d%d",&a[i].id,&a[i].arrivetime,&a[i].needtime); //fscanf()函數將數據讀入 printf("\n%3d%12d%15d",a[i].id,a[i].arrivetime,a[i].needtime); //輸出到屏幕 i++; }; if(fclose(fp)) //關閉文件 { printf("Can not close the file !\n"); exit(0); } n=i; } else if(choice==2)//僞隨機數的方式 { int i; srand((unsigned)time(0)); //參數seed是rand()的種子,用來初始化rand()的起始值。 //輸入做業數 n=rand()%23+1; printf("%d",n); for(i=0; i<=n; i++) { a[i].id=i; //做業到達時間 a[i].arrivetime=rand()%29+1; //做業運行時間 a[i].needtime=rand()%7+1; } printf("\n id 做業到達時間 做業運行所須要時間\n"); for(i=0; i<=n; i++) { printf("\n%3d%12d%15d",a[i].id,a[i].arrivetime,a[i].needtime); }} else{printf("請輸入進程數量\n"); scanf("%d",&n); getchar(); for(int i=0;i<n;i++) { printf("\n--------------------------\n"); printf("輸入第%d 個進程:",i+1); printf("\n--------------------------\n"); printf("輸入到達時間\n"); scanf("%d",&a[i].arrivetime); printf("輸入服務時間:\n"); scanf("%d",&a[i].needtime); getchar(); } } switch(j) {case 1: //system("CLS"); sortarrivetime(a,n);Fcfs(a,n);break; case 2://system("CLS"); sortservetime( a, n); SJFS(a,n);break; } } void SJFS(struct process_jcb a[],int n)//最短做業優先 { int i; a[0].finishtime=a[0].arrivetime+a[0].needtime; //完成時間=到達時間-服務時間 a[0].roundtime=a[0].finishtime-a[0].arrivetime; //週轉時間=完成時間-提交時間 a[0].Talltime=a[0].roundtime/a[0].needtime; //帶權時間=週轉時間/服務時間 for(i=1;i<n;i++) { if(a[i].arrivetime<a[i-1].finishtime) //當前到達時間在上一個做業結束時間以前 { a[i].finishtime=a[i-1].finishtime+a[i].needtime; //完成時間=上一個完成時間+服務時間 a[i].roundtime=a[i].finishtime-a[i].arrivetime; //週轉時間=完成時間-到達時間 a[i].Talltime=a[i].roundtime/a[i].needtime; //帶權時間=週轉時間/服務時間 } else //當前到達時間在上一個做業結束時間以後 { a[i].finishtime=a[i].arrivetime+a[i].needtime; a[i].roundtime=a[i].finishtime-a[i].arrivetime; (float) a[i].Talltime=(float)a[i].roundtime/(float)a[i].needtime; } } printf("\n 按最短做業優先算法完成進程調度.\n"); print(a,n); }