操作系統之早期磁盤調度算法 先來先服務(FCFS) 最短尋道時間優先(SSTF) java實現


磁盤調度 先來先服務(FCFS) 最短尋道時間優先(SSTF)

實驗內容:編寫一個程序處理磁盤調度中尋道時間的策略。

實驗目的:磁盤調度中尋道時間直接影響到數據訪問的快慢,處理好磁盤尋道時間是關鍵。

實驗題目

  • 采用先來先服務策略處理
  • 采用最短尋道策略處理

https://github.com/SKPrimin/HomeWork/tree/main/OperatingSystem/diskpatch

實驗原理

先來先服務(FCFS)

優點:公平、簡單,每個進程的請求都能依次得到處理
缺點:未對尋道進行優化,平均尋道時間較長

FCFSD

流程圖

FCFSP

最短尋道時間優先(SSTF)

優點:平均每次磁頭移動距離較近;尋道性能比 FCFS 好,但不能保證尋道時間最短

缺點:不能保證平均尋道時間最短且有可能引起某些請求的飢餓

SSTFD

流程圖

SSTFP

實現

java

數據結構和符號說明

DiskDispatch為一個工具類,定義了僅有其子類能使用的

四個變量 start為磁道開始點、track為將要訪問的磁道號數組、distanceSum移動距離總磁道數、movdistan為將要計算的移動距離數組。

方法distance(int a, int b)使用三元表達式計算出兩個磁盤的距離。

內部類Track是自定義數據類型,內含磁道號和磁針調度到本磁道移動距離。

FCFS類即先來先服務實現類

SSTF類即最短尋道時間優先實現類

DiskDispatch磁盤公有類

package com.process.diskpatch;

import java.util.ArrayList;

/**
 * @Author: SKPrimin
 * @Date 2021/12/17 13:27
 * @ClassName: DiskDispatch
 * @Description: TODO
 */

public class DiskDispatch {

    /**
     * start為磁道開始點
     * track為將要訪問的磁道號數組
     * distanceSum移動距離總磁道數
     * movdistan為將要計算的移動距離
     */
    protected int start;
    protected ArrayList<Integer> track;
    protected int distanceSum = 0;
    protected int[] movdistan;


    /**
     * 計算距離函數通過三元運算符返回兩數絕對值
     */
    protected int distance(int a, int b) {
        return a > b ? a - b : b - a;
    }


    /**
     * 定義內部類 磁道類 包含磁道號 要想訪問須達到的距離
     */
    static class Track {
        int diskName;
        int distance;
    }
}

FCFS先來先服務實現類

package com.process.diskpatch;

import java.util.ArrayList;
import java.util.Arrays;

/**
 * @Author: SKPrimin
 * @Date 2021/12/16 23:12
 * @ClassName: FCFS
 * @Description: TODO 先來先服務磁盤調度算法
 */

public class FCFS extends DiskDispatch {


    // 構造器
    public FCFS(int start, ArrayList<Integer> track) {
        this.start = start;
        this.track = track;
        movdistan = new int[track.size()];
    }

    /**
     * 調度執行函數,進行此次先來先服務磁盤調度
     */
    public void run() {
        // 初始化磁針位置
        int needle = start;
        for (int i = 0; i < track.size(); i++) {
            // 求出移動距離並保存
            movdistan[i] = distance(needle, track.get(i));
            distanceSum += movdistan[i];
            // 更新指針位置
            needle = track.get(i);
        }
    }

    @Override
    public String toString() {
        return "\n先來先服務FCFS張丞E01914168" +
                "\n從" + start + "號磁道開始" +
                "\n被訪問的下一個磁道號\t" + track +
                "\n移動距離(磁道數)\t" + Arrays.toString(movdistan) +
                "\n總道數:"+distanceSum+"\t平均尋道長度:" + String.format("%.2f", (double) distanceSum / track.size());
    }
}

SSTF最短尋道時間優先實現類

package com.process.diskpatch;

import java.util.ArrayList;
import java.util.Arrays;

/**
 * @Author: SKPrimin
 * @Date 2021/12/17 0:22
 * @ClassName: SSTF
 * @Description: TODO
 */

public class SSTF extends DiskDispatch {
    /**
     * trackSequence為SSTF調度的磁道號數組
     * len 為傳出的磁道號數目
     */
    private int[] trackSequence;
    private int len;


    // 構造器
    public SSTF(int start, ArrayList<Integer> track) {
        this.start = start;
        this.track = track;
        this.len = track.size();
        movdistan = new int[len];
        trackSequence = new int[len];
    }

    /**
     * 調度執行函數,進行此次最短尋道時間優先磁盤調度
     */
    public void run() {
        // 初始化磁針位置
        int needle = start;
        for (int i = 0; i < len; i++) {
            // 求出移動距離的磁道號以及移動距離
            Track tc = shortest(needle, track);
            // 將算出的將要訪問的下一磁道號、移動距離加入對應數組
            trackSequence[i] = tc.diskName;
            movdistan[i] = tc.distance;
            distanceSum += movdistan[i];
            // 更新指針位置以及磁道號列表,去除已經訪問的磁道號
            needle = tc.diskName;
            // 此處使用包裝類包裝,避免當成索引
            track.remove(Integer.valueOf(tc.diskName));
        }
    }

    /**
     * 在給定范圍內找出里磁針最近的磁道號
     *
     * @param needle 磁針當前位置
     * @param array  訪問磁道號數組,即查找范圍
     * @return 查找到的要訪問的磁道號
     */
    public Track shortest(int needle, ArrayList<Integer> array) {
        // 各變量初始化 先默認第一個是距離最近的磁道
        Track tc = new Track();
        tc.diskName = array.get(0);
        tc.distance = distance(needle, array.get(0));
        // 進過遍歷,若發現有離得更近的就替換
        for (int item :
                array) {
            if (distance(needle, item) < tc.distance) {
                tc.diskName = item;
                tc.distance = distance(needle, item);
            }
        }
        return tc;
    }

    @Override
    public String toString() {
        return "\n最短尋道時間優先SSTF張丞E01914168" +
                "\n從" + start + "號磁道開始" +
                "\n被訪問的下一個磁道號\t" + Arrays.toString(trackSequence) +
                "\n移動距離(磁道數)\t" + Arrays.toString(movdistan) +
                "\n總道數:"+distanceSum+"\t平均尋道長度:" + String.format("%.2f", (double) distanceSum / len);
    }
}

測試類

package com.process.diskpatch;

import java.util.ArrayList;

/**
 * @Author: SKPrimin
 * @Date 2021/12/17 0:20
 * @ClassName: Test
 * @Description: TODO 測試類 集中測試磁盤調度算法
 */

public class Test {
    public static void main(String[] args) {
        // 磁盤號順序
        int[] track = new int[]{98, 183, 37, 122, 14, 124, 65, 67};
        ArrayList<Integer> ta = new ArrayList<>();
        for (int t : track) {
            ta.add(t);
        }

        // 先來先服務
        FCFS ff = new FCFS(53, ta);
        ff.run();
        System.out.println(ff);

        //最短尋道時間優先
        SSTF st = new SSTF(53, ta);
        st.run();
        System.out.println(st);

    }
}

Python

def fifo(tracklist, needle):
    movdistan = []
    distanceSum = 0
    print(f"\n先來先服務FCFS\n從{needle}號磁道開始")
    print(f"被訪問的下一個磁道號\t移動距離(磁道數)")
    for index, item in enumerate(tracklist):
        # 算出移動距離並保存
        movdistan.append(abs(needle - item))
        distanceSum += movdistan[-1]
        # 更新磁針位置
        needle = item
        print(f"\t{item}\t\t\t\t\t{movdistan[-1]}")
    print(f"\n總道數:{distanceSum}\t平均尋道長度:{distanceSum / len(movdistan)}")
    return movdistan, distanceSum


def sstf(tracklist, needle):
    movdistan = []
    trackSequence = []
    distanceSum = 0
    print(f"\n最短尋道時間優先SSTF\n從{needle}號磁道開始")
    print(f"被訪問的下一個磁道號\t移動距離(磁道數)")
    length = len(tracklist)
    for i in range(length):
        # 求出移動距離的磁道號以及移動距離
        ts, distance = shortest(tracklist,needle )
        trackSequence.append(ts)
        movdistan.append(distance)
        # 將算出的將要訪問的下一磁道號、移動距離加入對應數組
        distanceSum += distance
        # 更新指針位置以及磁道號列表,去除已經訪問的磁道號
        needle = ts
        tracklist.remove(ts)
        print(f"\t{ts}\t\t\t\t\t{distance}")
    print(f"\n總道數:{distanceSum}\t平均尋道長度:{distanceSum / len(movdistan)}")



def shortest(array,needle):
    # 各變量初始化 先默認第一個是距離最近的磁道
    diskName = array[0]
    distance = abs(needle - array[0])
    # 進過遍歷,若發現有離得更近的就替換
    for item in array:
        if abs(needle - item) < distance:
            diskName = item
            distance = abs(needle - item)
    return diskName, distance

if __name__ == '__main__':

    track = [55, 58, 39, 18, 90, 160, 150, 38, 184]
    fifo(track, 100)
    sstf(track, 100)

運行截圖

image-20211217165645576


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM