操作系统实验4—磁盘调度
操作系統實驗4—磁盤調度
文章目錄
- 操作系統實驗4—磁盤調度
- 實驗描述
- 設計思路
- 上機代碼
- 測試結果
- 心得體會
實驗描述
實驗內容:
編寫一個磁盤調度程序,模擬操作系統對磁盤的調度。
實驗目的:
本實驗要求學生獨立設計并實現磁盤調度模擬程序,以加深對磁盤調度特點和各種磁盤調度算法的理解。
實驗要求:
可以隨機輸入磁道請求序列,當前磁頭位置和磁頭移動方向,支持先來先服務、最短尋道時間優先、掃描、循環掃描調度算法,能夠輸出磁頭移動經過的磁道序列。具體信息見測試用例格式說明。
測試用例格式如下:
輸入:
磁盤調度算法 當前磁頭位置 磁頭移動方向 磁道請求序列(磁道1,磁道2,磁道3,...) 其中: (1) 調度算法選項為:1----先來先服務2----最短尋道時間優先3----掃描法4----循環掃描法(2) 磁頭移動方向選項為:1----向磁頭號增大方向移動0----向磁頭號減小方向移動輸出:
磁頭移動經過的磁道序列(磁道1,磁道2,磁道3) 磁頭移動經過的總磁道數| 測試用例 1 | 1 53 1 98,183,37,122,14,124,65,67 | 53,98,183,37,122,14,124,65,67 640 | 1秒 | 64M | 0 |
| 測試用例 2 | 2 53 1 98,183,37,122,14,124,65,67 | 53,65,67,37,14,98,122,124,183 236 | 1秒 | 64M | 0 |
| 測試用例 3 | 3 53 1 98,183,37,122,14,124,65,67 | 53,65,67,98,122,124,183,37,14 299 | 1秒 | 64M | 0 |
| 測試用例 4 | 4 53 1 98,183,37,122,14,124,65,67 | 53,65,67,98,122,124,183,14,37 322 | 1秒 | 64M | 0 |
設計思路
雖然每次輸入的磁道數據只有磁道位置,但是在算法中需要計算每個磁道距離當前磁頭的位置,以及最短尋道時間優先算法中還有記錄該磁道是否已經訪問過,所以依然采用結構體數組的形式將需要用到的信息全部存儲起來。
struct node {int positon;//磁道位置int moved; //磁道與當前磁頭的距離int visit; //磁道是否被訪問過 }que[1010]; //初始磁道序列程序概要設計如下:
上機代碼
代碼使用 C++ 語言進行編寫
#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> using namespace std; struct node {int positon;//磁道位置int moved;//磁道與當前磁頭的距離int visit;//磁道是否被訪問過 }que[1010];//初始磁道序列 void input();//輸入函數 void output();//輸出函數 int dis(int a, int b);//兩個磁道距離的絕對值 void FCFS();//先來先服務 void SSTF();//最短尋道時間優先 void SCAN();//掃描法 void CSCAN();//循環掃描法 int sig, start, direction;//算法選擇標志,當前磁頭位置,磁頭移動方向 int num;//磁道數量 int order[1010];//磁頭訪問的磁道序列 int total;//磁頭訪問的總磁道數 const int isVis = 1;//該磁道被訪問過 const int noVis = 0;//該磁道沒被訪問過 const int bigger = 1;//向磁頭號增大方向移動 const int smaller = 0;//向磁頭號減小方向移動 int main() {//程序輸入input();//選擇算法switch (sig){case 1:FCFS(); break;case 2:SSTF(); break;case 3:SCAN(); break;case 4:CSCAN(); break;}//程序輸出output();return 0; } void input() {//freopen("osin.txt", "r", stdin);//freopen("osout.txt", "w", stdout);sig = 0;cin >> sig; //算法選擇標志start = 0;total = 0;cin >> start;//初始磁頭位置cin >> direction;//磁頭移動方向num = 0;char c;while (scanf("%d", &que[num].positon))//輸入磁道序列{que[num].moved = 0;que[num].visit = noVis;num++;c = getchar();if (c == '\n')//遇到換行符則輸入結束{break;}else if (c == ',')//遇到逗號則繼續讀取{continue;}} } void output() {for (int i = 0; i <= num; i++)//磁頭移動經過的磁道序列{if (i != num){printf("%d,", order[i]);}else{printf("%d\n", order[i]);}}printf("%d\n", total);//磁頭移動經過的總磁道數 } int dis(int a, int b) {return abs(a - b); } void FCFS() {order[0] = start;for (int i = 0; i < num; i++){que[i].moved = dis(que[i].positon, start);//計算磁頭移動距離order[i + 1] = que[i].positon;//更新訪問序列total += que[i].moved;//計算移動的總磁道數start = order[i + 1];//更新當前磁頭位置} } void SSTF() {int mini;//距磁頭距離最短的磁道號order[0] = start;//選擇num次最短距離for (int i = 0; i < num; i++){//計算本次距離for (int j = 0; j < num; j++){if (que[j].visit == noVis)//磁道沒被訪問過則與當前位置計算距離{que[j].moved = dis(que[j].positon, start);}else//否則把距離置為無窮大0x3f3f3f{que[j].moved = 0x3f3f3f;}}//找到本次的最短磁道mini = 0;for (int k = 0; k < num; k++){if (que[k].moved == 0x3f3f3f)//遇到0x3f3f3f就跳過{continue;}if (que[mini].moved > que[k].moved)//找到最短距離的磁道{mini = k;}}//更新訪問信息order[i + 1] = que[mini].positon;que[mini].moved = dis(que[mini].positon, start);total += que[mini].moved;que[mini].visit = isVis;start = que[mini].positon;} } void SCAN() {order[0] = start;//構造電梯int sorted[1010];for (int i = 0; i < num; i++){sorted[i] = que[i].positon;}sort(sorted, sorted + num);//距當前磁頭距離最短的磁道號int mini = 0;while (start >= sorted[mini]){mini++;}//開始運行電梯int ans = 1;if (direction == bigger)//向磁頭號增大方向移動{//電梯上升for (int i = mini; i < num; i++){order[ans] = sorted[i];ans++;}total += (sorted[num - 1] - start);//電梯下降for (int i = mini - 1; i >= 0; i--){order[ans] = sorted[i];ans++;}total += (sorted[num - 1] - sorted[0]);}else//向磁頭號減小方向移動{//電梯下降for (int i = mini - 1; i >= 0; i--){order[ans] = sorted[i];ans++;}total += (start - sorted[0]);//電梯上升for (int i = mini; i < num; i++){order[ans] = sorted[i];ans++;}total += (sorted[num - 1] - sorted[0]);} } void CSCAN() {order[0] = start;//構造電梯int sorted[1010];for (int i = 0; i < num; i++){sorted[i] = que[i].positon;}sort(sorted, sorted + num);//距當前磁頭距離最短的磁道號int mini = 0;while (start > sorted[mini]){mini++;}//開始運行電梯int ans = 1;if (direction == bigger)//向磁頭號增大方向移動{//電梯上升for (int i = mini; i < num; i++){order[ans] = sorted[i];ans++;}//電梯循環for (int i = 0; i < mini; i++){order[ans] = sorted[i];ans++;}//推導可得,total等于兩端長度的兩倍減去中間沒有覆蓋到的一段total += (2 * (sorted[num - 1] - sorted[0]) - (start - sorted[mini - 1]));}else//向磁頭號減小方向移動{//電梯下降for (int i = mini - 1; i >= 0; i--){order[ans] = sorted[i];ans++;}//電梯循環for (int i = num - 1; i >= mini; i--){order[ans] = sorted[i];ans++;}//推導可得,total等于兩端長度的兩倍減去中間沒有覆蓋到的一段total += (2 * (sorted[num - 1] - sorted[0]) - (sorted[mini] - start));} }測試結果
程序采用黑盒測試的方式,提交到 OJ 系統上進行在線評測
可以看到,OJ 的測試用例全部通過
心得體會
通過本次實驗,上機代碼模擬實現了四種磁盤調度算法,對操作系統內部的磁盤調度方式有了更深刻的認識和感受。SCAN 掃描法,從當前磁道沿著選定方向一直掃描到最外/內圈,直到沒有要訪問的磁道在沿反方向掃描,再沿反方向掃描。CSCAN 循環掃描法,自開始磁道始終沿一個方向掃描,直到沒有要訪問的磁道再從最里圈或最外圈掃描。因為計算磁頭每次的距離一定是正數,所以特別寫了一個計算距離的絕對值函數保證了計算數據的可靠性。計算循環掃描時,由數學邏輯推導出了相應的計算公式,讓程序顯得更加地簡潔和高效。
總結
以上是生活随笔為你收集整理的操作系统实验4—磁盘调度的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 操作系统实验2—实现动态分区分配模拟程序
- 下一篇: 如何设置使windows(dos)命令中