多級反饋隊列調度算法(附Python3實現代碼)

1、多級反饋隊列調度算法

多級反饋隊列調度算法是進程調度的一種算法,該調度算法能夠不用事先知道各類進程所需的執行時間,還能夠較好的知足各類類型進程的須要,是目前共認的一種較好的進程調度算法。python

那你可能立刻就要問了,多級反饋隊列調度算法究竟是怎麼調度的呢?我認爲不少算法均可以用一張圖+一句話來表達,因此接下來我儘可能用圖像來使這個算法看起來很是清晰。git

一句話:

多級反饋隊列調度算法,「多級」在於有多個不一樣優先級的隊列,「反饋」在於若是有進程加入優先級高的隊列時當即中止當前任務,轉去執行優先級高的隊列中進程,上述過程循環調度就造成多級反饋隊列調度算法。github

一張圖:

這裏寫圖片描述

上圖是一個調度的示例,進程有A(4),B(3),C(4),D(2),E(4),括號內是須要服務的時間。設第一隊列時間片q=1,由於該算法中時間片的規則爲:後一個時間片長度爲前一個的2倍,因此第二隊列時間片q=2,第三隊列時間片q=4。算法

若不能執行完,則放到下一個隊列尾部(橙色部分)app

到最後一個隊列的時候,則執行輪轉調度(RR)算法,也就是每次執行一個時間片長度的服務,直到循環執行完全部的進程。測試

2、Python3實現代碼

首先介紹一下程序中使用的結構體url

1.「進程/任務」結構體spa

class Process:
    def __init__(self,name,arrive_time,serve_time):
        self.name=name                              #進程名
        self.arrive_time=arrive_time                #到達時間
        self.serve_time=serve_time                  #須要服務的時間
        self.left_serve_time=serve_time             #剩餘須要服務的時間
        self.finish_time=0                          #完成時間
        self.cycling_time=0                         #週轉時間
        self.w_cycling_time=0                       #帶權週轉時間

進程的屬性有進程名,到達時間,須要服務的時間,剩餘須要服務的時間,完成時間,週轉時間,帶權週轉時間。其中週轉時間爲提交時間與完成時間的間隔;帶權週轉時間爲週轉時間/實際運行時間。.net

2.隊列code

class Queue:
    def __init__(self,level,process_list):
        self.level=level
        self.process_list=process_list
        self.q=0

    def size(self):
        return len(self.process_list)

    def get(self,index):
        return self.process_list[index]    

    def add(self,process):
        self.process_list.append(process)

    def delete(self,index):
        self.process_list.remove(self.process_list[index])

設置一個隊列,初始化方法須要給隊列的優先級,以及隊列中所包含的進程列表,順便定義獲取隊列一些屬性的方法。

而後是具體使用的算法程序:
3.輪轉調度算法(RR)

class RR:
    def __init__(self,process_list,q):
        self.process_list=process_list
        self.q=q
    def scheduling(self):
        process_list.sort(key=lambda x:x.arrive_time)#按照.arrive_time進行排序
        len_queue=len(self.process_list) #進程隊列的長度
        index=int(0)  #索引
        q=self.q      #時間片
        running_time=int(0)#已經運行了的時間

        #調度的循環
        while(True):
            #當前進程
            current_process=self.process_list[index%len_queue]
            #判斷當前進程是否已經被完成
            if current_process.left_serve_time>0: 
                #計算完成時間
                #還須要服務的時間大於等於時間片,則完成時間+時間片時間 此進程還沒結束
                #還須要服務的時間小於時間片,則完成時間在原來基礎上加上繼續服務的時間
                if current_process.left_serve_time>=q:
                    running_time+=q
                    #print(current_process.name,running_time,index)
                    current_process.left_serve_time-=q

                else :
                    #print('%s 還須要服務的時間小於當前時間片'%current_process.name)
                    running_time+=current_process.left_serve_time
                    current_process.left_serve_time=0


            #已完成
            if current_process.left_serve_time==0:
                #計算完成時間
                current_process.finish_time=running_time
                #計算週轉時間
                current_process.cycling_time=current_process.finish_time-current_process.arrive_time
                #計算帶權週轉時間
                current_process.w_cycling_time=float(current_process.cycling_time)/current_process.serve_time
                #打印
                print('%s 進程已完成的進程,詳細信息以下:'%current_process.name)
                print('進程名稱:%s ,完成時間: %d ,週轉時間:%d ,帶權週轉時間: %.2f'%(current_process.name,current_process.finish_time,current_process.cycling_time,current_process.w_cycling_time))
                #彈出
                self.process_list.remove(current_process)
                len_queue=len(self.process_list)
                #有進程完成任務後,index先回退,以後再加,以保持指向下一個須要調度的進程
                index-=1
            #index常規增長
            index+=1     

            #若是隊列中沒有進程則表示執行完畢
            if len(self.process_list)==0:
                break

            #改變index,避免由於index大於len,致使取模時出錯
            if index>=len(self.process_list):
                index=index%len_queue

多級反饋隊列調度算法用於執行最後一個隊列中的進程,若是單獨拿出來也是一個完整的算法實現代碼,下面的代碼中也有相應的測試代碼。

4.多級反饋隊列調度算法

class MulitlevedFeedbackQueue():
    def __init__(self,queue_list,q_first):
        self.queue_list=queue_list
        self.q_first=q_first
    def scheduling(self):
        q_list=self.queue_list  #當前隊列集合
        q_first=self.q_first                #第一個隊列的時間片

        for i in range(len(q_list)):
            #肯定每一個隊列的時間片
            if i==0:
                q_list[i].q=q_first
            else :
                q_list[i].q=q_list[i-1].q*2

            #從第一個隊列開始執行時間片
            #先判斷是不是最後一個隊列,最後一個隊列直接執行RR調度算法
            #不是最後一個隊列的話,就執行當前隊列時間片後判斷是否有必要加入到下一個隊列的末尾
            if i==len(q_list)-1:
                print('**************對最後一個隊列執行RR調度算法*************')
                #print(q_list[i].process_list[])
                #最後一個隊列從新設置到達時間
                for t in range(len(q_list[i].process_list)):
                    q_list[i].process_list[t].arrive_time=t
                rr_last_queue=RR(q_list[i].process_list,q_list[i].q)
                rr_last_queue.scheduling()
            else:
                currentQueue=q_list[i]

                index=int(0)
                while(True):
                    if currentQueue.get(index).left_serve_time>q_list[i].q:
                        currentQueue.get(index).left_serve_time-=q_list[i].q
                        print('第 %d 隊列時間片: %d'%(i,q_list[i].q))
                        print('進程沒有執行完畢,須要添加至下一隊列末尾:進程名稱:%s '%(currentQueue.get(index).name))
                        #將當前進程扔到下一個隊列的尾部
                        q_list[i+1].add(currentQueue.get(index))
                        index+=1  
                    else:
                        print('服務完成並彈出:',currentQueue.get(index).name)
                        currentQueue.get(index).left_serve_time=0
                        currentQueue.delete(index)

                    if index==currentQueue.size():
                        break

以上是多級反饋隊列調度算法,最後一個隊列使用第三個代碼片中的RR算法,其它的則按照上面算法詳情實現。

5.測試程序

''' 測試程序 '''    
if __name__=='__main__':
    '''產生進程'''
    process_list=[]
    processA=Process('A',0,4)
    processB=Process('B',1,3)
    processC=Process('C',2,4)
    processD=Process('D',3,2)
    processE=Process('E',4,4)
    process_list.append(processA),process_list.append(processB),process_list.append(processC)
    process_list.append(processD),process_list.append(processE)
    '''使用RR調度算法,時間片爲1'''
    print('#################################################################')
    print('---------------------------輪轉調度算法--------------------------')
    print('#################################################################')
    rr=RR(process_list,1)
    rr.scheduling()

    '''使用多級反饋隊列調度算法'''
    print()
    print('#################################################################')
    print('-----------------------測試多級反饋隊列調度算法----------------------')
    print('#################################################################')
    processA=Process('A',0,4)
    processB=Process('B',1,3)
    processC=Process('C',2,4)
    processD=Process('D',3,2)
    processE=Process('E',4,4)

    process_list0,process_list1,process_list2=[],[],[]
    process_list0.append(processA),process_list0.append(processB)
    process_list1.append(processC),process_list1.append(processD)
    process_list2.append(processE)

    #隊列
    queue_list=[]
    queue0=Queue(0,process_list0)
    queue1=Queue(1,process_list1)
    queue2=Queue(2,process_list2)
    queue_list.append(queue0),queue_list.append(queue1),queue_list.append(queue2)
    #使用多級反饋隊列調度算法,第一隊列時間片爲1
    mfq=MulitlevedFeedbackQueue(queue_list,1)
    mfq.scheduling()

實現結果:
這裏寫圖片描述

最後總結一下多級反饋隊列調度算法的優勢:

  • 不用事先知道各類進程所需的執行時間,還能夠較好的知足各類類型進程的須要

  • 既能使高優先級的做業獲得響應又能使短做業(進程)迅速完成。(對比FCFS與高優先響應比調度算法的缺陷)。

  • 兼顧長短做業,有較好的響應時間,可行性強,適用於各類做業環境。

代碼下載地址請戳
https://github.com/LIANGQINGYUAN/OperatingSystens/blob/master/Multilleved_Feedback_Queue.py

歡迎star,蟹蟹!!!

相關文章
相關標籤/搜索