作業系統-程序四個演算法實驗
阿新 • • 發佈:2018-12-26
實驗-程序描述與控制
一、實驗描述磁碟排程在多道程式設計的計算機系統中,各個程序可能會不斷提出不同的對磁碟進行讀/寫操作的請求。由於有時候這些程序的傳送請求的速度比磁碟響應的還要快,因此我們有必要為每個磁碟裝置建立一個等待佇列,常用的磁碟排程演算法有以下四種:先來先服務演算法(FCFS ),最短尋道時間優先演算法(SSTF),掃描演算法(SCAN ),迴圈掃描演算法(CSCAN )。
通過程式設計,預先設定一個磁軌個數及磁碟訪問序列。分別採用先來先服務演算法(FCFS ),最短尋道時間優先演算法(SSTF),掃描演算法(SCAN ),迴圈掃描演算法(CSCAN ),通過結果,計算出四種演算法的平均尋道的長度,比較四種演算法之間的差異和優勢。
二、實驗程式碼
#include <iostream> #include <vector> #include <fstream> using namespace std; typedef vector<int> vInt; //向量,動態陣列 struct OrderItem { int Data; bool IsVisited; }; typedef vector<OrderItem> Order; Order InitOrder; vInt TrackOrder; vInt MoveDistance; double AverageDistance; void InitDate(int &num); inline void Init(int disk); //行內函數(行內函數的程式碼會在任何呼叫它的地方展開) void FCFS(int disk); void SSTF(int disk); void SCAN(int disk); void CSCAN(int disk); void Show(int disk); int main() { int num; InitDate(num); char cmd; do { cout<<"選擇演算法:\n"<<"1-FCFS,2-SSTF,3-SCAN,4-CSCAN:\t"; int type;cin>>type; switch(type) { case 1:FCFS(num);break; case 2:SSTF(num);break; case 3:SCAN(num);break; case 4:CSCAN(num);break; } Show(num); cout<<"Continue? y or n?\t"; cin>>cmd; }while(cmd!='n'); return 0; } inline void Init(int disk) { TrackOrder.clear(); MoveDistance.clear(); for(int i = 0; i < disk; i++) { InitOrder[i].IsVisited = false; } } void InitDate(int &num) { //ifstream cin("data.txt"); cout<<"輸入磁軌個數"; cin>>num; cout<<"磁碟訪問序列"; for(int i=0; i<num; i++) { OrderItem oi; cin>>oi.Data; oi.IsVisited = false; InitOrder.push_back(oi); } } void FCFS(int disk) { cout<<"輸入開始磁碟號"; int start;cin>>start; cout<<"FCFS:"<<endl; int p = start; Init(disk); for(int i = 0 ; i < disk; i++ ) { TrackOrder.push_back(InitOrder[i].Data); int t = InitOrder[i].Data-p; MoveDistance.push_back(t>0?t:-t); InitOrder[i].IsVisited = true; p = InitOrder[i].Data; } } void SSTF(int disk) { cout<<"輸入開始磁碟號"; int start;cin>>start; cout<<"SSTF:"<<endl; Init(disk); int curp=0,dif=0; int p = start; for(int i = 0; i < disk; i++) { int temp = 0; for(int j = 0 ; j < disk; j++) { if(InitOrder[j].IsVisited == false) { temp = p-InitOrder[j].Data>0? p-InitOrder[j].Data:-(p-InitOrder[j].Data); if(dif==0||temp<dif) { dif = temp; curp = j; } } } InitOrder[curp].IsVisited = true; TrackOrder.push_back(InitOrder[curp].Data); MoveDistance.push_back(dif); p = InitOrder[curp].Data; dif = 0; } } void SCAN(int disk) { cout<<"輸入開始磁碟號"; int start;cin>>start; cout<<"選擇訪問方向:0-磁軌號遞增1-磁軌號遞減\t"; int dir; cin>>dir; cout<<"SSTF:"<<endl; Init(disk); int curp=0,dif=0,cdir=dir,max=InitOrder[0].Data,min=max; for(int i =1; i<disk;i++) { if(max<InitOrder[i].Data) max = InitOrder[i].Data; if(min>InitOrder[i].Data) min = InitOrder[i].Data; } int p = start; for(int k = 0; k< disk; k++) { int temp = 0; for(int j = 0 ; j < disk; j++) { if(cdir==0&&p>InitOrder[j].Data||cdir==1&&p<InitOrder[j].Data) continue; if(InitOrder[j].IsVisited == false) { temp = p-InitOrder[j].Data>0? p-InitOrder[j].Data:-(p-InitOrder[j].Data); if(dif==0||temp<dif) { dif = temp; curp = j; } } } if(dir==0&&InitOrder[curp].Data==max)cdir = 1; if(dir==1&&InitOrder[curp].Data==min)cdir = 0; InitOrder[curp].IsVisited = true; TrackOrder.push_back(InitOrder[curp].Data); MoveDistance.push_back(dif); p = InitOrder[curp].Data; dif = 0; } } void CSCAN(int disk) { cout<<"輸入開始磁碟號"; int start;cin>>start; cout<<"選擇訪問方向:0-磁軌號遞增1-磁軌號遞減\t"; int dir; cin>>dir; cout<<"CSSTF:"<<endl; Init(disk); int curp=0,dif=-1,max=InitOrder[0].Data,min=max,mmin=0,mmax=0; for(int i =1; i<disk;i++)//找到磁軌序列中最小和最大的磁軌號及下標 { if(max<InitOrder[i].Data) { max = InitOrder[i].Data; mmax = i; } if(min>InitOrder[i].Data) { min = InitOrder[i].Data; mmin=i; } } int p = start;//p表示上一個訪問的磁軌號 for(int k = 0; k < disk; k++) { int temp = 0; for(int j = 0 ; j < disk; j++)//查詢下一個要訪問的磁軌 { if(dir==0&&p>InitOrder[j].Data||dir==1&&p<InitOrder[j].Data) continue; if(InitOrder[j].IsVisited == false)//dir方向且未被訪問的項 { temp = p-InitOrder[j].Data>0? (p-InitOrder[j].Data):(InitOrder[j].Data-p); if(dif==-1||temp<dif) { dif = temp; curp = j;//找到下一個被訪問的磁軌 } } } InitOrder[curp].IsVisited = true;//訪問 TrackOrder.push_back(InitOrder[curp].Data); MoveDistance.push_back(dif); p = InitOrder[curp].Data; //達到極限點 if(dir==0&&InitOrder[curp].Data==max&&InitOrder[mmin].IsVisited==false) { //從最小項開始 TrackOrder.push_back(min); InitOrder[mmin].IsVisited = true; MoveDistance.push_back(p-TrackOrder[mmin]>=0? p-TrackOrder[mmin]:TrackOrder[mmin]-p); curp = mmin; } if(dir==1&&InitOrder[curp].Data==min&&InitOrder[mmax].IsVisited==false) { TrackOrder.push_back(max); InitOrder[mmax].IsVisited = true; MoveDistance.push_back(p-TrackOrder[mmin]>=0? p-TrackOrder[mmin]:TrackOrder[mmin]-p); curp = mmax; } p = InitOrder[curp].Data; dif = -1; } } void Show(int disk) { cout<<"被訪問的下一個磁軌號\t"<<"移動距離"<<endl; int sum=0; for(int i = 0 ; i <disk; i++) { sum+=MoveDistance[i]; cout<<"\t"<<TrackOrder[i]<<"\t\t "<<MoveDistance[i]<<endl; } AverageDistance = (double)sum/disk; cout<<"平均尋道長度:"<<AverageDistance<<endl; }