多級反饋隊列調度演算法 C語言類比實現

來源:互聯網
上載者:User

多級反饋隊列調度演算法:
1、設定多個就緒隊列,並給隊列賦予不同的優先順序數,第一個最高,依次遞減。
2、賦予各個隊列中進程執行時間片的大小,優先順序越高的隊列,時間片越小。
3、當一個新進程進入記憶體後,首先將其放入一個對列末尾,如果在一個時間片
結束時尚未完成,將其轉入第二隊列末尾。
4、當一個進程從一個對列移至第n個隊列後,便在第n個隊列中採用時間片輪轉執行完。
5、僅當時間片空閑時,才調度第二個隊列中的進程。
(1~i-1)空閑時,才調度i,如果處理機正在第i隊列中運行,又有新進程進入優先權較高
隊列,則新進程搶佔處理機,將正在啟動並執行進程放入第i隊列隊尾,將處理機分給新進程。
#include <stdio.h><br />#include <stdlib.h><br />#include <string.h><br />typedef struct node /*進程節點資訊*/<br />{<br />char name[20]; /*進程的名字*/<br />int prio; /*進程的優先順序*/<br />int round; /*分配CPU的時間片*/<br />int cputime; /*CPU執行時間*/<br />int needtime; /*進程執行所需要的時間*/<br />char state; /*進程的狀態,W——就緒態,R——執行態,F——完成態*/<br />int count; /*記錄執行的次數*/<br />struct node *next; /*鏈表指標*/<br />}PCB;<br />typedef struct Queue /*多級就緒隊列節點資訊*/<br />{<br />PCB *LinkPCB; /*就緒隊列中的進程隊列指標*/<br />int prio; /*本就緒隊列的優先順序*/<br />int round; /*本就緒隊列所分配的時間片*/<br />struct Queue *next; /*指向下一個就緒隊列的鏈表指標*/<br />}ReadyQueue;<br />PCB *run=NULL,*finish=NULL; /*定義三個隊列,就緒隊列,執行隊列和完成隊列*/<br />ReadyQueue *Head = NULL; /*定義第一個就緒隊列*/<br />int num; /*進程個數*/<br />int ReadyNum; /*就緒隊列個數*/<br />void Output(); /*進程資訊輸出函數*/<br />void InsertFinish(PCB *in); /*將進程插入到完成隊列尾部*/<br />void InsertPrio(ReadyQueue *in); /*建立就緒隊列,規定優先數越小,優先順序越低*/<br />void PrioCreate(); /*建立就緒隊列輸入函數*/<br />void GetFirst(ReadyQueue *queue); /*取得某一個就緒隊列中的隊頭進程*/<br />void InsertLast(PCB *in,ReadyQueue *queue); /*將進程插入到就緒隊列尾部*/<br />void ProcessCreate(); /*進程建立函數*/<br />void RoundRun(ReadyQueue *timechip); /*時間片輪轉調度演算法*/<br />void MultiDispatch(); /*多級調度演算法,每次執行一個時間片*/</p><p>int main(void)<br />{<br />PrioCreate(); /*建立就緒隊列*/<br />ProcessCreate();/*建立就緒進程隊列*/<br />MultiDispatch();/*演算法開始*/<br />Output(); /*輸出最終的調度序列*/<br />return 0;<br />}<br />void Output() /*進程資訊輸出函數*/<br />{<br />ReadyQueue *print = Head;<br />PCB *p;<br />printf("進程名/t優先順序/t輪數/tcpu時間/t需要時間/t進程狀態/t計數器/n");<br />while(print)<br />{<br /> if(print ->LinkPCB != NULL)<br /> {<br /> p=print ->LinkPCB;<br /> while(p)<br /> {<br /> printf("%s/t%d/t%d/t%d/t%d/t/t%c/t/t%d/n",p->name,p->prio,p->round,p->cputime,p->needtime,p->state,p->count);<br /> p = p->next;<br /> }<br /> }<br /> print = print->next;<br />}<br />p = finish;<br />while(p!=NULL)<br />{<br /> printf("%s/t%d/t%d/t%d/t%d/t/t%c/t/t%d/n",p->name,p->prio,p->round,p->cputime,p->needtime,p->state,p->count);<br /> p = p->next;<br />}<br />p = run;<br />while(p!=NULL)<br />{<br /> printf("%s/t%d/t%d/t%d/t%d/t/t%c/t/t%d/n",p->name,p->prio,p->round,p->cputime,p->needtime,p->state,p->count);<br /> p = p->next;<br />}</p><p>}<br />void InsertFinish(PCB *in) /*將進程插入到完成隊列尾部*/<br />{<br />PCB *fst;<br />fst = finish;</p><p>if(finish == NULL)<br />{<br /> in->next = finish;<br /> finish = in;<br />}<br />else<br />{<br /> while(fst->next != NULL)<br /> {<br /> fst = fst->next;<br /> }<br /> in ->next = fst ->next;<br /> fst ->next = in;<br />}<br />}<br />void InsertPrio(ReadyQueue *in) /*建立就緒隊列,規定優先數越小,優先順序越低*/<br />{<br />ReadyQueue *fst,*nxt;<br />fst = nxt = Head;</p><p>if(Head == NULL) /*如果沒有隊列,則為第一個元素*/<br />{<br /> in->next = Head;<br /> Head = in;<br />}<br />else /*查到合適的位置進行插入*/<br />{<br /> if(in ->prio >= fst ->prio) /*比第一個還要大,則插入到隊頭*/<br /> {<br /> in->next = Head;<br /> Head = in;<br /> }<br /> else<br /> {<br /> while(fst->next != NULL) /*移動指標尋找第一個別它小的元素的位置進行插入*/<br /> {<br /> nxt = fst;<br /> fst = fst->next;<br /> }</p><p> if(fst ->next == NULL) /*已經搜尋到隊尾,則其優先順序數最小,將其插入到隊尾即可*/<br /> {<br /> in ->next = fst ->next;<br /> fst ->next = in;<br /> }<br /> else /*插入到隊列中*/<br /> {<br /> nxt = in;<br /> in ->next = fst;<br /> }<br /> }<br />}<br />}<br />void PrioCreate() /*建立就緒隊列輸入函數*/<br />{<br />ReadyQueue *tmp;<br />int i;</p><p>printf("輸入就緒隊列的個數:/n");<br />scanf("%d",&ReadyNum);</p><p>printf("輸入每個就緒隊列的CPU時間片:/n");<br />for(i = 0;i < ReadyNum; i++)<br />{<br /> if((tmp = (ReadyQueue *)malloc(sizeof(ReadyQueue)))==NULL)<br /> {<br /> perror("malloc");<br /> exit(1);<br /> }<br /> scanf("%d",&(tmp->round)); /*輸入此就緒隊列中給每個進程所分配的CPU時間片*/<br /> tmp ->prio = 50 - tmp->round; /*設定其優先順序,時間片越高,其優先順序越低*/<br /> tmp ->LinkPCB = NULL; /*初始化其串連的進程隊列為空白*/<br /> tmp ->next = NULL;<br /> InsertPrio(tmp); /*按照優先順序從高到低,建立多個就緒隊列*/<br />}<br />}<br />void GetFirst(ReadyQueue *queue) /*取得某一個就緒隊列中的隊頭進程*/<br />{<br />run = queue ->LinkPCB;</p><p>if(queue ->LinkPCB != NULL)<br />{<br /> run ->state = 'R';<br /> queue ->LinkPCB = queue ->LinkPCB ->next;<br /> run ->next = NULL;<br />}<br />}<br />void InsertLast(PCB *in,ReadyQueue *queue) /*將進程插入到就緒隊列尾部*/<br />{<br />PCB *fst;<br />fst = queue->LinkPCB;</p><p>if( queue->LinkPCB == NULL)<br />{<br /> in->next = queue->LinkPCB;<br /> queue->LinkPCB = in;<br />}<br />else<br />{<br /> while(fst->next != NULL)<br /> {<br /> fst = fst->next;<br /> }<br /> in ->next = fst ->next;<br /> fst ->next = in;<br />}<br />}<br />void ProcessCreate() /*進程建立函數*/<br />{<br />PCB *tmp;<br />int i;</p><p>printf("輸入進程的個數:/n");<br />scanf("%d",&num);<br />printf("輸入進程名字和進程所需時間:/n");<br />for(i = 0;i < num; i++)<br />{<br /> if((tmp = (PCB *)malloc(sizeof(PCB)))==NULL)<br /> {<br /> perror("malloc");<br /> exit(1);<br /> }<br /> scanf("%s",tmp->name);<br /> getchar(); /*吸收斷行符號符號*/<br /> scanf("%d",&(tmp->needtime));<br /> tmp ->cputime = 0;<br /> tmp ->state ='W';<br /> tmp ->prio = 50 - tmp->needtime; /*設定其優先順序,需要的時間越多,優先順序越低*/<br /> tmp ->round = Head ->round;<br /> tmp ->count = 0;<br /> InsertLast(tmp,Head); /*按照優先順序從高到低,插入到就緒隊列*/<br />}<br />}<br />void RoundRun(ReadyQueue *timechip) /*時間片輪轉調度演算法*/<br />{</p><p>int flag = 1;</p><p>GetFirst(timechip);<br />while(run != NULL)<br />{<br /> while(flag)<br /> {<br /> run->count++;<br /> run->cputime++;<br /> run->needtime--;<br /> if(run->needtime == 0) /*進程執行完畢*/<br /> {<br /> run ->state = 'F';<br /> InsertFinish(run);<br /> flag = 0;<br /> }<br /> else if(run->count == timechip ->round)/*時間片用完*/<br /> {<br /> run->state = 'W';<br /> run->count = 0; /*計數器清零,為下次做準備*/<br /> InsertLast(run,timechip);<br /> flag = 0;<br /> }<br /> }<br /> flag = 1;<br /> GetFirst(timechip);<br />}<br />}<br />void MultiDispatch() /*多級調度演算法,每次執行一個時間片*/<br />{<br />int flag = 1;<br />int k = 0;</p><p>ReadyQueue *point;<br />point = Head;</p><p>GetFirst(point);<br />while(run != NULL)<br />{<br /> Output();<br /> if(Head ->LinkPCB!=NULL)<br /> point = Head;<br /> while(flag)<br /> {<br /> run->count++;<br /> run->cputime++;<br /> run->needtime--;<br /> if(run->needtime == 0) /*進程執行完畢*/<br /> {<br /> run ->state = 'F';<br /> InsertFinish(run);<br /> flag = 0;<br /> }<br /> else if(run->count == run->round)/*時間片用完*/<br /> {<br /> run->state = 'W';<br /> run->count = 0; /*計數器清零,為下次做準備*/<br /> if(point ->next!=NULL)<br /> {<br /> run ->round = point->next ->round;/*設定其時間片是下一個就緒隊列的時間片*/<br /> InsertLast(run,point->next); /*將進程插入到下一個就緒隊列中*/<br /> flag = 0;<br /> }<br /> else<br /> {<br /> RoundRun(point); /*如果為最後一個就緒隊列就調用時間片輪轉演算法*/<br /> break;<br /> }<br /> }<br /> ++k;<br /> if(k == 3)<br /> {<br /> ProcessCreate();<br /> }<br /> }<br /> flag = 1;<br /> if(point ->LinkPCB == NULL)/*就緒隊列指標下移*/<br /> point =point->next;<br /> if(point ->next ==NULL)<br /> {<br /> RoundRun(point);<br /> break;<br /> }<br /> GetFirst(point);<br />}<br />}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.