操作系统实验报告18:硬盘柱面访问调度算法
操作系統實驗報告18
實驗內容
- 實驗內容:硬盤調度。
- 編寫 C 程序模擬實現課件 Lecture25 中的硬盤柱面訪問調度算法
包括 FCFS、SSTF、SCAN、C-SCAN、LOOK、C-LOOK,并設計輸入用例驗證結果。
- 編寫 C 程序模擬實現課件 Lecture25 中的硬盤柱面訪問調度算法
實驗環境
- 架構:Intel x86_64 (虛擬機)
- 操作系統:Ubuntu 20.04
- 匯編器:gas (GNU Assembler) in AT&T mode
- 編譯器:gcc
技術日志
實驗內容原理
- 磁盤
- 磁盤或硬盤為現代計算機系統提供大量外存。在概念上磁盤比較簡單。每個盤片為平的圓狀,如同CD一樣。盤片的兩面都涂著磁質材料。通過在盤片上進行磁性記錄可以保存信息。
- 讀寫磁頭“飛行”在一個盤片的表面上方。磁頭附著在磁臂上,磁臂將所有磁頭作為一個整體而一起移動。盤片的表面邏輯地分成圓形磁道,再細分為扇區。同一磁臂位置的磁道集合形成了柱面。每個磁盤驅動器有數千個同心柱面,而每個磁道可能包括數百個扇區。常見磁盤驅動器的存儲容量按GB來計算。
- 移動磁頭的磁盤裝置圖:
- 當使用磁盤時,驅動器電機高速旋轉磁盤。大多數驅動器每秒旋轉60~250次,按每分鐘轉數(RPM)來計。普通驅動器的轉速為5400、7200、10000和15000RPM。磁盤速度有兩部分。
- 傳輸速率是在驅動器和計算機之間的數據流的速率。
- 定位時間或隨機訪問時間包括兩部分:
- 尋道時間(移動磁臂到所要柱面的所需時間)
- 旋轉延遲(旋轉磁臂到所要扇區的所需時間)
- 典型的磁盤可以按每秒數兆字節的速率來傳輸,并且尋道時間和旋轉延遲為數毫秒。
- 磁盤或硬盤為現代計算機系統提供大量外存。在概念上磁盤比較簡單。每個盤片為平的圓狀,如同CD一樣。盤片的兩面都涂著磁質材料。通過在盤片上進行磁性記錄可以保存信息。
- 磁盤調度
- 操作系統的職責之一是有效使用硬件。
- 對于磁盤驅動器,滿足這個要求具有較快的訪問速度和較寬的磁盤帶寬。
- 對于磁盤,訪問時間包括兩個主要部分
- 尋道時間是磁臂移動磁頭到包含目標扇區的柱面的時間。
- 旋轉延遲是磁盤旋轉目標扇區到磁頭下的額外時間。
- 假設尋道時間約等價于尋道距離
- 磁盤帶寬是傳輸字節的總數除以從服務請求開始到最后傳遞結束時的總時間。
- 通過管理磁盤IO請求的處理次序,可以改善訪問時間和帶寬。
- 每當進程需要進行磁盤I/O操作時,它就向操作系統發出一個系統調用。這個請求需要些信息
- 這個操作是輸入還是輸出
- 傳輸的磁盤地址是什么
- 傳輸的內存地址是什么
- 傳輸的扇區數是多少
- 如果所需的磁盤驅動器和控制器空閑,則立即處理請求。如果磁盤驅動器或控制器忙,則任何新的服務請求都會添加磁盤驅動器的待處理請求隊列。對于具有多個進程的一個多道程序系統,磁盤隊列可能有多個待處理的請求。因此,當一個請求完成時,操作系統可以使用磁盤調度算法選擇哪個待處理的請求服務。
- 操作系統的職責之一是有效使用硬件。
- 磁盤調度算法
- FCFS先來先服務調度算法
- 按順序處理I/O請求
- 對所有進程都是公平的
- 如果有許多進程/請求,則在性能上接近隨機調度
- 在全局上會有之字形效應,通常不提供最快的服務
- SSTF最短尋道時間優先調度算法
- SSTF從當前磁頭位置選擇具有最小尋道時間的請求。
- 也稱為最短尋道距離優先(SSDF),因為計算距離更加容易。
- 是一種最近鄰法。
- 這個算法更加偏重于處理中間的柱面請求。
- SSTF調度是SJF調度的一種形式;可能會導致某些請求無法滿足。
- SSTF從當前磁頭位置選擇具有最小尋道時間的請求。
- SCAN掃描算法
- 磁臂從磁盤的一端開始,向另一端移動;在移過每個柱面時,處理請求。當到達磁盤的另一端時,磁頭移動方向反轉,并繼續處理。磁頭連續來回掃描磁盤。
- C-SCAN循環掃描算法
- 是SCAN的一個變種,以提供更均勻的等待時間。
- 像SCAN一樣,C-SCAN移動磁頭從磁盤一端到磁盤另一端,并且處理行程上的請求。然而,當磁頭到達另一端時,它立即返回到磁盤的開頭,而并不處理任何回程上的請求
- LOOK調度算法和C-LOOK算法
- SCAN和C-SCAN在磁盤的整個寬度內移動磁臂。實際上,這兩種算法通常都不是按這種方式實施的。更常見的是,磁臂只需移到一個方向的最遠請求為止。遵循這種模式的SCAN算法和C-SCAN算法分別稱為LOOK和 C-LOOK調度,因為它們在向特定方向移動時查看是否會有請求。
- FCFS先來先服務調度算法
設計報告
代碼設計
//HDD_scheduling.c文件 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h>#define CYLINDER_REQ_NUM 8 // I/O請求塊的柱面數目 #define CYLINDER_NUM 200 // 總的柱面數目// 取一個數的絕對值 int abs_int(int num);// 硬盤柱面訪問調度算法 void FCFS(int *cylinders, int *cylinder_req, int cylinder_head); void SSTF(int *cylinders, int *cylinder_req, int cylinder_head); void SCAN(int *cylinders, int *cylinder_req, int cylinder_head, int head_dir); void C_SCAN(int *cylinders, int *cylinder_req, int cylinder_head, int head_dir); void LOOK(int *cylinders, int *cylinder_req, int cylinder_head, int head_dir); void C_LOOK(int *cylinders, int *cylinder_req, int cylinder_head, int head_dir);// 找到距離當前磁頭最近的請求處理的柱面 int find_cylinder_min_seek_dis(int *cylinders, int cylinder_head); // 將I/O請求塊的柱面在硬盤上設置相應的請求 void set_cylinders(int *cylinders, int *cylinder_req); // 打印I/O請求塊的柱面的信息 void print_cylinder_req(int *cylinder_req); // 打印開始時磁頭掃描方向 void print_head_dir(int head_dir);// 取一個數的絕對值 int abs_int(int num) {if (num >= 0) {return num;} else {return -num;} }// 先來先服務調度算法 void FCFS(int *cylinders, int *cylinder_req, int cylinder_head) {printf("\n--------------------------------------------------------\n");printf("HDD Scheduling Algorithm: FCFS\n");print_cylinder_req(cylinder_req);printf("\n");// 初始化硬盤柱面,設置相應柱面請求處理memset(cylinders, 0, CYLINDER_NUM * sizeof(int));set_cylinders(cylinders, cylinder_req);int head_move_sum = 0;printf("head's movement: ");// 打印一開始磁頭處于柱面位置if (cylinders[cylinder_head] == 0) {printf("%d ", cylinder_head);}for(int i = 0; i < CYLINDER_REQ_NUM; ++i) {int cylinder_id = cylinder_req[i];// 直接按照柱面請求順序處理請求柱面printf("%d ", cylinder_id);// 處理后的柱面在硬盤上的請求數減一cylinders[cylinder_id]--;// 將磁頭移動距離加到磁頭移動總距離中head_move_sum += abs_int(cylinder_head - cylinder_id);// 磁頭位置為處理完的柱面位置cylinder_head = cylinder_id;}printf("\nThe total movement of head = %d cylinders\n", head_move_sum);printf("--------------------------------------------------------\n"); }// 最短尋道時間優先調度算法 void SSTF(int *cylinders, int *cylinder_req, int cylinder_head) {printf("\n--------------------------------------------------------\n");printf("HDD Scheduling Algorithm: SSTF\n");print_cylinder_req(cylinder_req);printf("\n");// 初始化硬盤柱面,設置相應柱面請求處理memset(cylinders, 0, CYLINDER_NUM * sizeof(int));set_cylinders(cylinders, cylinder_req);int head_move_sum = 0;printf("head's movement: ");// 打印一開始磁頭處于柱面位置if (cylinders[cylinder_head] == 0) {printf("%d ", cylinder_head);}for(int i = 0; i < CYLINDER_REQ_NUM; ++i) {int cylinder_id = find_cylinder_min_seek_dis(cylinders, cylinder_head);// 直接按照柱面請求順序處理請求柱面printf("%d ", cylinder_id);// 處理后的柱面在硬盤上的請求數減一cylinders[cylinder_id]--;// 將磁頭移動距離加到磁頭移動總距離中head_move_sum += abs_int(cylinder_head - cylinder_id);// 磁頭位置為處理完的柱面位置cylinder_head = cylinder_id;}printf("\nThe total movement of head = %d cylinders\n", head_move_sum);printf("--------------------------------------------------------\n"); }// 掃描調度算法 void SCAN(int *cylinders, int *cylinder_req, int cylinder_head, int head_dir) {printf("\n--------------------------------------------------------\n");printf("HDD Scheduling Algorithm: SCAN\n");print_cylinder_req(cylinder_req);print_head_dir(head_dir);printf("\n");// 初始化硬盤柱面,設置相應柱面請求處理memset(cylinders, 0, CYLINDER_NUM * sizeof(int));set_cylinders(cylinders, cylinder_req);int pre_cylinder_head = cylinder_head;int head_move_sum = 0;printf("head's movement: ");// 打印一開始磁頭處于柱面位置if (cylinders[cylinder_head] == 0) {printf("%d ", cylinder_head);}// 向一個方向掃描直到盡頭while (cylinder_head >= 0 && cylinder_head < CYLINDER_NUM) {// 如果磁頭在請求處理的柱面上while (cylinders[cylinder_head] > 0) {printf("%d ", cylinder_head);// 將磁頭移動距離加到磁頭移動總距離中head_move_sum += abs_int(cylinder_head - pre_cylinder_head);// 更新磁頭上一次處在的位置pre_cylinder_head = cylinder_head;// 處理后的柱面在硬盤上的請求數減一cylinders[cylinder_head]--;}// 如果head_dir為0,向朝0的方向掃描if (head_dir == 0) {cylinder_head--;} else {// 如果head_dir為1,向朝CYLINDER_NUM的方向掃描cylinder_head++;}}// 令磁頭到達一側盡頭if (cylinder_head == -1) {cylinder_head++;}if (cylinder_head == CYLINDER_NUM) {cylinder_head--;}if (pre_cylinder_head != cylinder_head) {printf("%d ", cylinder_head);head_move_sum += abs_int(cylinder_head - pre_cylinder_head);pre_cylinder_head = cylinder_head;}// 調轉掃描方向if (head_dir == 0) {head_dir = 1;} else {head_dir = 0;}// 向另一個方向繼續掃描while (cylinder_head >= 0 && cylinder_head < CYLINDER_NUM) {while (cylinders[cylinder_head] > 0) {printf("%d ", cylinder_head);head_move_sum += abs_int(cylinder_head - pre_cylinder_head);pre_cylinder_head = cylinder_head;cylinders[cylinder_head]--;}if (head_dir == 0) {cylinder_head--;} else {cylinder_head++;}}printf("\nThe total movement of head = %d cylinders\n", head_move_sum);printf("--------------------------------------------------------\n"); }// 循環掃描調度算法 void C_SCAN(int *cylinders, int *cylinder_req, int cylinder_head, int head_dir) {printf("\n--------------------------------------------------------\n");printf("HDD Scheduling Algorithm: C-SCAN\n");print_cylinder_req(cylinder_req);print_head_dir(head_dir);printf("\n");// 初始化硬盤柱面,設置相應柱面請求處理memset(cylinders, 0, CYLINDER_NUM * sizeof(int));set_cylinders(cylinders, cylinder_req);int pre_cylinder_head = cylinder_head;int head_move_sum = 0;printf("head's movement: ");// 打印一開始磁頭處于柱面位置if (cylinders[cylinder_head] == 0) {printf("%d ", cylinder_head);}// 向一個方向掃描直到盡頭while (cylinder_head >= 0 && cylinder_head < CYLINDER_NUM) {// 如果磁頭在請求處理的柱面上while (cylinders[cylinder_head] > 0) {printf("%d ", cylinder_head);// 將磁頭移動距離加到磁頭移動總距離中head_move_sum += abs_int(cylinder_head - pre_cylinder_head);// 更新磁頭上一次處在的位置pre_cylinder_head = cylinder_head;// 處理后的柱面在硬盤上的請求數減一cylinders[cylinder_head]--;}// 如果head_dir為0,向朝0的方向掃描if (head_dir == 0) {cylinder_head--;} else {// 如果head_dir為1,向朝CYLINDER_NUM的方向掃描cylinder_head++;}}// 令磁頭到達一側盡頭if (cylinder_head == -1) {cylinder_head++;}if (cylinder_head == CYLINDER_NUM) {cylinder_head--;}if (pre_cylinder_head != cylinder_head) {printf("%d ", cylinder_head);head_move_sum += abs_int(cylinder_head - pre_cylinder_head);pre_cylinder_head = cylinder_head;}// 令磁頭直接到達另一側盡頭if (cylinder_head == 0) {cylinder_head = CYLINDER_NUM - 1;} else if (cylinder_head == CYLINDER_NUM - 1) {cylinder_head = 0;}pre_cylinder_head = cylinder_head;head_move_sum += CYLINDER_NUM - 1;if (cylinders[cylinder_head] == 0) {printf("%d ", cylinder_head);}// 向同一方向繼續掃描while (cylinder_head >= 0 && cylinder_head < CYLINDER_NUM) {while (cylinders[cylinder_head] > 0) {printf("%d ", cylinder_head);head_move_sum += abs_int(cylinder_head - pre_cylinder_head);pre_cylinder_head = cylinder_head;cylinders[cylinder_head]--;}if (head_dir == 0) {cylinder_head--;} else {cylinder_head++;}}printf("\nThe total movement of head = %d cylinders\n", head_move_sum);printf("--------------------------------------------------------\n"); }// LOOK電梯調度算法 void LOOK(int *cylinders, int *cylinder_req, int cylinder_head, int head_dir) {printf("\n--------------------------------------------------------\n");printf("HDD Scheduling Algorithm: LOOK\n");print_cylinder_req(cylinder_req);print_head_dir(head_dir);printf("\n");// 初始化硬盤柱面,設置相應柱面請求處理memset(cylinders, 0, CYLINDER_NUM * sizeof(int));set_cylinders(cylinders, cylinder_req);int pre_cylinder_head = cylinder_head;int head_move_sum = 0;printf("head's movement: ");// 打印一開始磁頭處于柱面位置if (cylinders[cylinder_head] == 0) {printf("%d ", cylinder_head);}// 找到兩個方向的最遠請求int cylinder_req_min = cylinder_req[0];int cylinder_req_max = cylinder_req[0];for(int i = 0; i < CYLINDER_REQ_NUM; ++i) {int cylinder_id = cylinder_req[i];if (cylinder_req_min > cylinder_id) {cylinder_req_min = cylinder_id;}if (cylinder_req_max < cylinder_id) {cylinder_req_max = cylinder_id;}}// 如果磁頭一開始在兩個最遠請求外側,那么首先掃到最近一側的盡頭if (cylinder_head < cylinder_req_min) {cylinder_head = cylinder_req_min;head_move_sum += cylinder_req_min - cylinder_head;} else if (cylinder_head > cylinder_req_max) {cylinder_head = cylinder_req_max;head_move_sum += cylinder_req_max - cylinder_req_min;}// 向一個方向掃描while (cylinder_head >= cylinder_req_min && cylinder_head <= cylinder_req_max) {// 如果磁頭在請求處理的柱面上while (cylinders[cylinder_head] > 0) {printf("%d ", cylinder_head);// 將磁頭移動距離加到磁頭移動總距離中head_move_sum += abs_int(cylinder_head - pre_cylinder_head);// 更新磁頭上一次處在的位置pre_cylinder_head = cylinder_head;// 處理后的柱面在硬盤上的請求數減一cylinders[cylinder_head]--;}// 如果head_dir為0,向朝0的方向掃描if (head_dir == 0) {cylinder_head--;} else {// 如果head_dir為1,向朝CYLINDER_NUM的方向掃描cylinder_head++;}}// 令磁頭到達一側最遠請求if (cylinder_head == cylinder_req_min - 1) {cylinder_head = cylinder_req_min;}if (cylinder_head == cylinder_req_max + 1) {cylinder_head = cylinder_req_max;}// 調轉掃描方向if (head_dir == 0) {head_dir = 1;} else {head_dir = 0;}// 向另一個方向繼續掃描while (cylinder_head >= cylinder_req_min && cylinder_head <= cylinder_req_max) {while (cylinders[cylinder_head] > 0) {printf("%d ", cylinder_head);head_move_sum += abs_int(cylinder_head - pre_cylinder_head);pre_cylinder_head = cylinder_head;cylinders[cylinder_head]--;}if (head_dir == 0) {cylinder_head--;} else {cylinder_head++;}}printf("\nThe total movement of head = %d cylinders\n", head_move_sum);printf("--------------------------------------------------------\n"); }// C-LOOK循環電梯調度算法 void C_LOOK(int *cylinders, int *cylinder_req, int cylinder_head, int head_dir) {printf("\n--------------------------------------------------------\n");printf("HDD Scheduling Algorithm: C-LOOK\n");print_cylinder_req(cylinder_req);print_head_dir(head_dir);printf("\n");// 初始化硬盤柱面,設置相應柱面請求處理memset(cylinders, 0, CYLINDER_NUM * sizeof(int));set_cylinders(cylinders, cylinder_req);int pre_cylinder_head = cylinder_head;int head_move_sum = 0;printf("head's movement: ");// 打印一開始磁頭處于柱面位置if (cylinders[cylinder_head] == 0) {printf("%d ", cylinder_head);}// 找到兩個方向的最遠請求int cylinder_req_min = cylinder_req[0];int cylinder_req_max = cylinder_req[0];for(int i = 0; i < CYLINDER_REQ_NUM; ++i) {int cylinder_id = cylinder_req[i];if (cylinder_req_min > cylinder_id) {cylinder_req_min = cylinder_id;}if (cylinder_req_max < cylinder_id) {cylinder_req_max = cylinder_id;}}// 如果磁頭一開始在兩個最遠請求外側,那么首先掃到最近一側的盡頭if (cylinder_head < cylinder_req_min) {cylinder_head = cylinder_req_min;head_move_sum += cylinder_req_min - cylinder_head;} else if (cylinder_head > cylinder_req_max) {cylinder_head = cylinder_req_max;head_move_sum += cylinder_req_max - cylinder_req_min;}// 向一個方向掃描while (cylinder_head >= cylinder_req_min && cylinder_head <= cylinder_req_max) {// 如果磁頭在請求處理的柱面上while (cylinders[cylinder_head] > 0) {printf("%d ", cylinder_head);// 將磁頭移動距離加到磁頭移動總距離中head_move_sum += abs_int(cylinder_head - pre_cylinder_head);// 更新磁頭上一次處在的位置pre_cylinder_head = cylinder_head;// 處理后的柱面在硬盤上的請求數減一cylinders[cylinder_head]--;}// 如果head_dir為0,向朝0的方向掃描if (head_dir == 0) {cylinder_head--;} else {// 如果head_dir為1,向朝CYLINDER_NUM的方向掃描cylinder_head++;}}// 令磁頭到達另一側最遠請求head_move_sum += cylinder_req_max - cylinder_req_min;if (cylinder_head == cylinder_req_min - 1) {cylinder_head = cylinder_req_max;}if (cylinder_head == cylinder_req_max + 1) {cylinder_head = cylinder_req_min;}pre_cylinder_head = cylinder_head;// 向同一方向繼續掃描while (cylinder_head >= cylinder_req_min && cylinder_head <= cylinder_req_max) {while (cylinders[cylinder_head] > 0) {printf("%d ", cylinder_head);head_move_sum += abs_int(cylinder_head - pre_cylinder_head);pre_cylinder_head = cylinder_head;cylinders[cylinder_head]--;}if (head_dir == 0) {cylinder_head--;} else {cylinder_head++;}}printf("\nThe total movement of head = %d cylinders\n", head_move_sum);printf("--------------------------------------------------------\n"); }// 找到距離當前磁頭最近的請求處理的柱面 int find_cylinder_min_seek_dis(int *cylinders, int cylinder_head) {// 朝0方向查找的變量int find_head_dir0 = cylinder_head;// 朝CYLINDER_NUM方向查找的變量int find_head_dir1 = cylinder_head;while (find_head_dir0 >= 0 || find_head_dir1 < CYLINDER_NUM) {// 每次兩個變量移動相同距離查找,當找到有請求的柱面,就是距離磁頭最近的柱面,直接返回if (find_head_dir0 >= 0) {if (cylinders[find_head_dir0] > 0) {return find_head_dir0;}find_head_dir0--;}if (find_head_dir1 < CYLINDER_NUM) {if (cylinders[find_head_dir1] > 0) {return find_head_dir1;}find_head_dir1++;}}// 沒有請求處理的柱面則返回-1return -1; }// 將I/O請求塊的柱面在硬盤上設置相應的請求 void set_cylinders(int *cylinders, int *cylinder_req) {for(int i = 0; i < CYLINDER_REQ_NUM; ++i) {int cylinder_id = cylinder_req[i];// 可能同一柱面不止一個請求,所以請求加一cylinders[cylinder_id]++;} }// 打印I/O請求塊的柱面的信息 void print_cylinder_req(int *cylinder_req) {printf("cylinder request: ");for(int i = 0; i < CYLINDER_REQ_NUM; ++i) {printf("%d ", cylinder_req[i]);}printf("\n"); }// 打印開始時磁頭掃描方向 void print_head_dir(int head_dir) {printf("The direction of head movement in the beginning: toward cylinder ");if (head_dir == 0) {printf("0\n");} else {printf("%d\n", CYLINDER_NUM - 1);} }int main () {int cylinders[CYLINDER_NUM];int cylinder_req[CYLINDER_REQ_NUM];int cylinder_head;int head_dir;// 生成隨機數的方式產生測試樣例/*srand((unsigned) time(NULL));int num;for (int i = 0; i < CYLINDER_REQ_NUM; ++i) {num = rand() % CYLINDER_NUM;cylinder_req[i] = num;}num = rand() % CYLINDER_NUM;cylinder_head = num;num = rand() % 2;head_dir = num;*/// 手動輸入的方式產生測試樣例printf("Please input the queue with requests for cylinders:\n");for(int i = 0; i < CYLINDER_REQ_NUM; ++i) {scanf("%d", &cylinder_req[i]);}printf("Please input the head's position of cylinder: ");scanf("%d", &cylinder_head);printf("Please input the direction of head movement(0: toward cylinder 0, 1: toward cylinder %d): ", CYLINDER_NUM - 1);scanf("%d", &head_dir);FCFS(cylinders, cylinder_req, cylinder_head);SSTF(cylinders, cylinder_req, cylinder_head);SCAN(cylinders, cylinder_req, cylinder_head, head_dir);C_SCAN(cylinders, cylinder_req, cylinder_head, head_dir);LOOK(cylinders, cylinder_req, cylinder_head, head_dir);C_LOOK(cylinders, cylinder_req, cylinder_head, head_dir); }執行命令:
gcc HDD_scheduling.c ./a.out驗證各個磁盤調度算法的正確性
在宏定義處設置I/O請求塊的柱面數目、總的柱面數目:
#define CYLINDER_REQ_NUM 8 // I/O請求塊的柱面數目 #define CYLINDER_NUM 200 // 總的柱面數目測試用例1:
首先按照教材上的用例測試:
#define CYLINDER_REQ_NUM 8 // I/O請求塊的柱面數目 #define CYLINDER_NUM 200 // 總的柱面數目98 183 37 122 14 124 65 67 53 098 183 37 122 14 124 65 67 53 1先來先服務調度算法:
可以看到,
一開始,磁頭所在的柱面為53;
然后按照I/O請求塊的柱面順序依次處理柱面請求,得到的磁頭移動路徑和磁頭移動總距離與教材相同。
過程符合先來先服務調度算法。
最短尋道時間優先調度算法:
可以看到,
一開始,磁頭所在的柱面為53;
然后按照距離當前磁頭所在柱面最短距離的柱面依次處理柱面請求,得到的磁頭移動路徑和磁頭移動總距離與教材相同。
過程符合最短尋道時間優先調度算法。
掃描調度算法:
首先磁頭向朝0方向掃描:
可以看到,
一開始,磁頭所在的柱面為53;
然后按照掃描方向的經過柱面依次處理柱面請求,到達0后,再向朝柱面199方向依次掃描,得到的磁頭移動路徑和磁頭移動總距離與教材相同。
過程符合掃描調度算法。
如果首先磁頭向朝柱面199方向掃描:
可以看到,
一開始,磁頭所在的柱面為53;
然后按照掃描方向的經過柱面依次處理柱面請求,到達柱面199后,再向朝0方向依次掃描。
過程符合掃描調度算法。
循環掃描調度算法:
首先磁頭向朝0方向掃描:
可以看到,
一開始,磁頭所在的柱面為53;
然后按照掃描方向的經過柱面依次處理柱面請求,到達0后,直接到達柱面199,再向朝0方向依次掃描。
過程符合循環掃描調度算法。
如果首先磁頭向朝柱面199方向掃描:
可以看到,
一開始,磁頭所在的柱面為53;
然后按照掃描方向的經過柱面依次處理柱面請求,到達柱面199后,直接到達柱面0,再向朝柱面199方向依次掃描,得到的磁頭移動路徑和磁頭移動總距離與教材相同。
過程符合循環掃描調度算法。
LOOK電梯調度算法:
首先磁頭向朝0方向掃描:
可以看到,
一開始,磁頭所在的柱面為53;
然后按照掃描方向的經過柱面依次處理柱面請求,到達朝0方向最遠的柱面請求柱面14后,再向朝柱面199方向依次掃描,得到的磁頭移動路徑和磁頭移動總距離與教材相同。
過程符合LOOK電梯調度算法。
如果首先磁頭向朝柱面199方向掃描:
可以看到,
一開始,磁頭所在的柱面為53;
然后按照掃描方向的經過柱面依次處理柱面請求,到達朝柱面199方向最遠的柱面請求柱面183后,再向朝0方向依次掃描。
過程符合LOOK電梯調度算法。
C-LOOK循環電梯調度算法:
首先磁頭向朝0方向掃描:
可以看到,
一開始,磁頭所在的柱面為53;
然后按照掃描方向的經過柱面依次處理柱面請求,到達朝0方向最遠的請求柱面14后,直接到達朝柱面199方向最遠的請求柱面183,再向朝0方向依次掃描。
過程符合C-LOOK循環電梯調度算法。
如果首先磁頭向朝柱面199方向掃描:
可以看到,
一開始,磁頭所在的柱面為53;
然后按照掃描方向的經過柱面依次處理柱面請求,到達朝柱面199方向最遠的請求柱面183后,直接到達朝0方向最遠的請求柱面14,再向柱面199方向依次掃描,得到的磁頭移動路徑和磁頭移動總距離與教材相同。
過程符合C-LOOK循環電梯調度算法。
測試用例2:
#define CYLINDER_REQ_NUM 8 // I/O請求塊的柱面數目 #define CYLINDER_NUM 200 // 總的柱面數目176 17 23 42 5 21 186 92 156 0執行截圖:
可以看到,磁頭的移動路徑和移動總距離都正確。
測試用例3:
#define CYLINDER_REQ_NUM 8 // I/O請求塊的柱面數目 #define CYLINDER_NUM 200 // 總的柱面數目81 87 138 193 99 99 79 67 14 1這個樣例中,磁頭一開始的位置比朝0方向的最遠請求柱面距離0更近,中間有兩個柱面請求為同一個柱面。
執行截圖:
可以看到,磁頭的移動路徑和移動總距離都正確。
LOOK算法和C-LOOK算法的移動路徑和移動總距離都相同,因為磁頭第一次朝一個方向掃時就已經處理完所有的柱面請求,符合算法。
測試用例4:
#define CYLINDER_REQ_NUM 8 // I/O請求塊的柱面數目 #define CYLINDER_NUM 200 // 總的柱面數目53 53 43 53 43 53 53 53 53 1這個樣例中,磁頭一開始的位置和第一個請求的柱面位置一樣,中間有多個重復請求的柱面位置。
執行截圖:
可以看到,磁頭的移動路徑和移動總距離都正確。
C-LOOK算法中,磁頭首先到達最遠請求柱面53,然后直接到達另一側的最遠請求柱面43,所有磁頭移動總距離為0,符合算法。
總結
以上是生活随笔為你收集整理的操作系统实验报告18:硬盘柱面访问调度算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 操作系统实验报告17:请求页面置换算法
- 下一篇: 用Unity3D实现简单的井字棋小游戏