1. 程式人生 > >【作業系統實驗】磁碟排程演算法(python)

【作業系統實驗】磁碟排程演算法(python)

實驗六:磁碟排程演算法:

本實驗是模擬作業系統的磁碟尋道方式,運用磁碟訪問順序的不同來設計磁碟的排程演算法。

(1)    實現的磁碟排程演算法有FCFSSSTFSCANCSCAN NStepSCAN演算法。

(2)    設定開始磁軌號尋道範圍,依據起始掃描磁軌號和最大磁軌號數,隨機產生要進行尋道的磁軌號序列。

(3)   選擇磁碟排程演算法,顯示該演算法的磁軌訪問順序,計算出移動的磁軌總數和平均尋道總數。

(4)   按演算法的尋道效率進行排序,並對各演算法的效能進行分析比較。

import random
import copy
TRACK_MAX_COUNT = 100                 #磁軌的總數
TRACK_REQUEST_COUNT = 10              #請求訪問的磁軌數量
TRACK_START = 50
SCAN_DIRECTION = 1                    # 1表示向磁軌號增加的方向掃描,0表示向磁軌號減小的方向
N_STEPSCAN = 4                        # 表示請求佇列被劃分為長度為 N 的子佇列

#*********************先來先服務排程演算法**************************/
def FCFS(track_request):
    queue_FCFS = track_request.copy()
    queue_FCFS.insert(0,TRACK_START)
    return queue_FCFS



#**********************最短尋道時間優先排程演算法********************
def findNearest(current,track_request,visited):
    minDis = TRACK_MAX_COUNT
    minIndex = -1
    for i in range(len(track_request)):
        if visited[i] == False:
            dis = abs( current - track_request[i])
            if dis < minDis:
                minDis = dis
                minIndex = i
    visited[minIndex] = True
    return minIndex, minDis

def SSTF(track_request):
    visited = [False] * TRACK_REQUEST_COUNT
    queue_FCFS = []
    current = TRACK_START                               #起始的磁軌
    for i in range(len(track_request)+1):
        index, dis = findNearest(current, track_request, visited)
        queue_FCFS.append(current)
        current = track_request[index]
    return queue_FCFS



    queue_SCAN.append(TRACK_START)
    current = TRACK_START#**********************掃描排程演算法********************
def SCAN(track_request):
    global SCAN_DIRECTION
    queue_SCAN = []

    track_request_copy = copy.deepcopy(track_request)
    track_request_copy.sort()
    while track_request_copy.__len__() != 0:
        if SCAN_DIRECTION == 1:
            for track in track_request_copy.copy():
                if TRACK_START <= track:
                    queue_SCAN.append(track)
                    track_request_copy.remove(track)
            SCAN_DIRECTION = 0

        if SCAN_DIRECTION == 0:
            track_request_copy.reverse()
            for track in track_request_copy.copy():
                if TRACK_START >= track:
                    queue_SCAN.append(track)
                    current = track
                    track_request_copy.remove(track)
            SCAN_DIRECTION = 1
    return queue_SCAN



#**********************迴圈掃描排程演算法********************
def CSCAN(track_request):
    global SCAN_DIRECTION
    queue_CSCAN = []
    queue_CSCAN.append(TRACK_START)
    track_request_copy = copy.deepcopy(track_request)
    track_request_copy.sort()
    i = 0
    is_find = False

    if SCAN_DIRECTION ==1:
        while i < track_request_copy.__len__():
            if (TRACK_START <= track_request_copy[i] ) & (is_find == False):
                index = i
                i = 0
                is_find = True
            if is_find == True:
                queue_CSCAN.append(track_request_copy[index % TRACK_REQUEST_COUNT])
                index += 1
            i +=1

    if SCAN_DIRECTION ==0:
        track_request_copy.reverse()
        while i < track_request_copy.__len__():
            if (TRACK_START >= track_request_copy[i] ) & (is_find == False):
                index = i
                i = 0
                is_find = True
            if is_find == True:
                queue_CSCAN.append(track_request_copy[index % TRACK_REQUEST_COUNT])
                index += 1
                current = track_request_copy[index % TRACK_REQUEST_COUNT]
            i +=1

    return queue_CSCAN

#****************** NStepSCAN演算法 ************************
def NStepSCAN(track_request):
    queue_NStepSCAN = []
    queue_NStepSCAN.append(TRACK_START)
    swap_track_request = []
    Count = 0
    for i in range(TRACK_REQUEST_COUNT ):         #將佇列進行劃分成長度為N_STEPSCAN的佇列
        #print(track_request[i])
        if i == TRACK_REQUEST_COUNT -1:
            swap_track_request.append(track_request[i])
            sub_queue_NstepQueue = SCAN(swap_track_request)
            sub_queue_NstepQueue.remove(TRACK_START)
            print('子序列為')
            print(sub_queue_NstepQueue)
            queue_NStepSCAN += sub_queue_NstepQueue
            break
        if Count < N_STEPSCAN:
            #print(track_request)
            swap_track_request.append(track_request[i])
            #print(swap_track_request)
        else:
            sub_queue_NstepQueue= SCAN(swap_track_request)
            sub_queue_NstepQueue.remove(TRACK_START)
            print('子序列為')
            print(sub_queue_NstepQueue)
            queue_NStepSCAN += sub_queue_NstepQueue
            swap_track_request.clear()
            swap_track_request.append(track_request[i])
            Count = 0
        Count += 1
    return queue_NStepSCAN

def caculate(queue):
    print('訪問的磁軌序列為: ',end = '')
    print(queue)
    sum_gap = sum([(abs(queue[i] - queue[i - 1])) for i in range(1, len(queue))])
    print('移動的磁軌數為:%d' % sum_gap)
    print('平均移動的磁軌數為:%.2f' % (sum_gap/TRACK_REQUEST_COUNT))
    print("")

if __name__ == '__main__':
    track_request = [None] * TRACK_REQUEST_COUNT
    for i in range(TRACK_REQUEST_COUNT):
        track_request[i] = random.randint(0, TRACK_MAX_COUNT)

    print('每次生成的磁軌序列是隨機的,對於不同的序列演算法的演算法的效能是不一樣的,'
          '通過多次比較觀察結果,SSTF是演算法中移動的磁軌數最少的')

    print("TRACK SEQUECE:    ")
    print(track_request)
    print('')

    print("FCFS:    ")
    caculate(FCFS(track_request))

    print("SSTF:    ")
    caculate(SSTF(track_request))

    print("SCAN:    ")
    caculate(SCAN(track_request))

    print("CSCAN:   ")
    caculate(CSCAN(track_request))

    print("NStepSCAN:   ")
    caculate(NStepSCAN(track_request))