1. 程式人生 > >作業系統實驗之磁碟排程

作業系統實驗之磁碟排程

實驗要求

  • 選擇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

馬後炮

除錯過程

除錯基本沒有出現很大的問題,主要出現的是一些小細節的地方,比如陣列越界等問題,經過除錯後便能正常執行。

小結

磁碟排程實驗是作業系統三次實驗裡最簡單的一個,主要考察的實際是對排程思想的理解,實際程式碼的難度並不大,程式碼上的難點頂多就於陣列的遍歷。