操作系統實驗之磁盤調度

實驗要求

  • 選擇1~3種磁盤調度算法(先來先服務法、最短尋道時間優先、電梯算法)模擬實現磁盤調度;
  • 能夠輸入當前磁頭的位置、磁頭移動方向、磁道訪問請求序列等;
  • 計算磁頭移動的總磁道數;
  • 能夠顯示磁盤調度結果(磁頭依次訪問的磁道號順序等)

我選擇了先來先服務法FCFS、最短尋道時間優先SSTF、電梯算法SCAN三種調度算法,代碼用Java實現。
源碼已上傳到本人github上,建議先看源碼。

實驗原理

代碼結構

HardDrive類表示磁盤,其私有成員有tracks表示訪問序列數組,trackSet表示磁道訪問集合,用HashSet實現Set接口,headAt表示磁頭處於磁道位置,direction表示在SCAN調度算法裏磁頭移動的方向,distance表示磁頭移動的總距離,method表示調度方法

代碼思路

整體思路

用tracks數組表示訪問序列,用於FCFS調度。trackSet用於遍歷訪問序列,獲得每次離磁頭最近的磁道。headAt在每次移動磁頭後記錄位置,distance用來保存每次headAt移動前後距離的絕對值的累加和。
構造一個HardDrive對象,並將參數tracks、headAt、direction、method參數帶入,根據調度方法不同輸出不同的結果。

FCFS

先來先服務調度比較簡單,用數組表示順序訪問序列,遍歷數組,輸出下一個數組元素i,計算數組該元素i和當前headAt距離並保存到distance中,修改磁頭headAt位置。遍歷結束後輸出distance。

    private void FCFS() {
        System.out.print("尋道順序爲:" + headAt + " ");
        for (int i : tracks) {
            System.out.print(i + " ");
            this.distance += Math.abs(headAt - i);
            headAt = i;
        }
        System.out.println();
        System.out.println("總路程=" + this.distance);
    }

SSTF

最短尋道時間優先調度使用trackSet,遍歷trackSet每次選出一個離磁頭最近的磁道並輸出,把距離累加到distance中,將磁頭移到該磁道,將該磁道從trackSet中移除,直到trackSet爲空。最後輸出總路程。

        System.out.print("尋道順序爲:" + headAt + " ");
        while (!trackSet.isEmpty()) {
            Iterator<Integer> iterator = trackSet.iterator();
            int chosenOne = iterator.next();
            while (iterator.hasNext()) {
                int t = iterator.next();
                if (Math.abs(t - this.headAt) < Math.abs(chosenOne - this.headAt))
                    chosenOne = t;
            }
            System.out.print(chosenOne + " ");
            this.distance += Math.abs(this.headAt - chosenOne);
            this.headAt = chosenOne;
            trackSet.remove(chosenOne);
        }
        System.out.println();
        System.out.println("總路程=" + this.distance);
    }

SCAN

電梯調度算法首先將當前訪問序列進行冒泡排序,然後在排序後的數組中找到當前磁頭的序號head,根據輸入的磁頭移動方向分別移動並輸出,同時把距離累加到distance中,最後輸出總路程。

    private void SCAN() {
        System.out.print("尋道順序爲:" + headAt + " ");
        int[] orderTracks = this.tracks.clone();
        for (int i = 0; i < orderTracks.length; i++) {
            for (int j = i + 1; j < orderTracks.length; j++) {
                if (orderTracks[i] > orderTracks[j]) {
                    int t = orderTracks[i];
                    orderTracks[i] = orderTracks[j];
                    orderTracks[j] = t;
                }
            }
        }
        int head = 0;
        for (int i = 0; i < orderTracks.length&&orderTracks[i]<headAt; i++) {
            head++;
        }
        if (direction) {
            for (int i = head; i < orderTracks.length; i++) {
                System.out.print(orderTracks[i] + " ");
                this.distance += Math.abs(this.headAt - orderTracks[i]);
                this.headAt = orderTracks[i];
            }
            for (int i = head - 1; i >= 0; i--) {
                System.out.print(orderTracks[i] + " ");
                this.distance += Math.abs(this.headAt - orderTracks[i]);
                this.headAt = orderTracks[i];
            }
        } else {
            for (int i = head; i < orderTracks.length; i++) {
                System.out.print(orderTracks[i] + " ");
                this.distance += Math.abs(this.headAt - orderTracks[i]);
                this.headAt = orderTracks[i];
            }
            for (int i = head - 1; i >= 0; i--) {
                System.out.print(orderTracks[i] + " ");
                this.distance += Math.abs(this.headAt - orderTracks[i]);
                this.headAt = orderTracks[i];
            }
        }
        System.out.println();
        System.out.println("總路程=" + this.distance);
    }

實驗結果

測試用例

int[] tracks = {98, 183, 37, 122, 14, 124, 65, 67};

FCFS

1.FCFS 2.SSTF 3.SCAN
請輸入調度算法:1
請輸入磁頭起始位置:
53
請輸入方向(0.左 1.右):
0
尋道順序爲:53 98 183 37 122 14 124 65 67
總路程=640

Process finished with exit code 0

SSTF

1.FCFS 2.SSTF 3.SCAN
請輸入調度算法:2
請輸入磁頭起始位置:
53
請輸入方向(0.左 1.右):
0
尋道順序爲:53 65 67 37 14 98 122 124 183
總路程=236

Process finished with exit code 0

SCAN

1.FCFS 2.SSTF 3.SCAN
請輸入調度算法:3
請輸入磁頭起始位置:
53
請輸入方向(0.左 1.右):
0
尋道順序爲:53 37 14 65 67 98 122 124 183
總路程=208

Process finished with exit code 0

馬後炮

調試過程

調試基本沒有出現很大的問題,主要出現的是一些小細節的地方,比如數組越界等問題,經過調試後便能正常運行。

小結

磁盤調度實驗是操作系統三次實驗裏最簡單的一個,主要考察的實際是對調度思想的理解,實際代碼的難度並不大,代碼上的難點頂多就於數組的遍歷。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章