-------------------------------腦瓜疼腦瓜疼,哎呀媽呀腦瓜疼------------------------
多級反饋隊列算法
問題簡介
在操作系統中,多進程運行的次序是不一樣的,這種時候就需要選擇執行的順序。
在分時系統中多采用循環輪轉調度算法,系統規定一個時間片,每個進程被調度的時候分得一個時間片,當這一時間片用完時,
該進程轉為就緒態並進入就緒隊列末尾。這就是循環輪轉算法的主要思路。

(下面的代碼只考慮P1-----P5的進程)
簡單循環輪轉調度
當CPU空閑時,選取就緒隊列首元素,賦予時間片。當進程時間片用完時,就釋放CPU控制權,進入就緒隊列末尾,CPU控制權給
下一個處於就緒隊列首元素。
狀態圖如下:

具體思路
本來想用隊列來算的,但是考慮到指針的問題,又因為剛學了循環鏈表,所以考慮用循環鏈表來存放數據。
(循環列表和一般鏈表唯一一個區別就是最后一個結點本來是p->next=NULL,現在就把頭結點和尾結點相連就行,即p->next=head)
下面是結構體的里面的內容,放入進程的名字以及需要運行的時間和等待時間
struct pcb { char name[10]; //進程名稱 int need, turn; //進程運行時間和已等待時間 struct pcb *next; };
然后,給鏈表賦初值
//給隊列1 賦值 struct pcb *create1() { int num(0); struct pcb *rq1 = NULL; struct pcb *p = NULL; struct pcb *t;//head頭結點 p當前結點 t下一結點 struct pcb *next; while(num<len1) { t = (struct pcb*)malloc(sizeof(struct pcb)); if (num == 0) { rq1 = t; p = t; } else if (num == len1 - 1) { p->next = t; p = t; t->next = rq1; } else { p->next = t; p = t; t->next = NULL; } init(t); ++num; } return rq1; } void init(struct pcb*p) { cin >> p->name >> p->need >> p->turn; }
在計算運行時間的時候,
1.比如說第一個進程的運行時間小於或等於時間片的長度,所以,就把時間加上去,並將每個進程的等待時間都加上這個進程的運行時間。
並且將正在運行的進程的need賦值為0。這樣是為了將need標記為已經運行完的了,以后若再碰到就跳過這個結點。
2.再比如說第一個進程的運行時間大於時間片的長度,就將該進程的need減去一個時間片的長度,並且將指針移到下個結點,相當於把這個結點放到隊列尾部。
再把各個進程的等待時間加上一個時間片的長度。就這樣反復的循環,知道所有結點的need全部變為0的時候就跳出來。
直接上代碼吧:
#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<algorithm> #include<cstdio> //#define NULL 0 #include<queue> using namespace std; const int maxn = 100; struct pcb { char name[10]; //進程名稱 int need, turn; //進程運行時間和已等待時間 struct pcb *next; }; int len1(0), len2(0); //兩個進程的長度 int clock(0); //時鍾 int time(0);//時間片大小 int TIME; //rq1運行完的時間 void init(struct pcb*p) { cin >> p->name >> p->need >> p->turn; } //給隊列1 賦值 struct pcb *create1() { int num(0); struct pcb *rq1 = NULL; struct pcb *p = NULL; struct pcb *t;//head頭結點 p當前結點 t下一結點 struct pcb *next; while(num<len1) { t = (struct pcb*)malloc(sizeof(struct pcb)); if (num == 0) { rq1 = t; p = t; } else if (num == len1 - 1) { p->next = t; p = t; t->next = rq1; } else { p->next = t; p = t; t->next = NULL; } init(t); ++num; } return rq1; } //當運行時間小於時間片大小時候的求和函數,即將每個進程的等待時間加上當前進程運行的時間 void sum1(struct pcb *p) { struct pcb *t; t = p; while (p->next != t) { if (p->need != 0) { p->turn += t->need; p = p->next; } else p = p->next;; } p->turn += t->need; } //當運行時間大於時間片大小時候的求和函數,即將每個進程的等待時間加上當前進程運行的時間 void sum2(struct pcb *p) { struct pcb *t; t = p; while (p->next != t) { if (p->need != 0) { p->turn += time; p = p->next; } else p=p->next; } p->turn += time; } //求隊列1里面各個進程運行完畢需要花費的時間 void fun1(struct pcb *h) { int num, count; while (1) { //最后一個的next ==NULL num = 0; count = len1; struct pcb *t = h; //將h賦給t if (t->need <= time && t->need != 0) { //如果這個進程運行時間小於時間片且非零說明沒有弄完 clock += t->need; sum1(t); h->need = 0; cout << h->name << "的運行時間是" << h->turn << endl; } if(t->need>time) { clock += time; t->need -= time; sum2(t); } h = h->next; struct pcb *temp = h; while (count--) { if (temp->need == 0) { num++; } temp = temp->next; } if (num == 4) break; } while (h->need == 0) { h = h->next; } while (h->need>time) { h->need -= time; h->turn += time; } // return (h->turn + h->need); TIME = h->turn + h->need; cout<<h->name<<"的運行時間是 "<< h->turn + h->need << endl; // cout << h->turn + h->need << endl; } int main() { cout << "請輸入時間片大小:"; cin >> time; cout << endl; cout << "請輸入進程1和進程2的數量:"; cin >> len1 >> len2; cout << endl; struct pcb *rq1, *rq2; cout << "請輸入進程1的信息:" << endl; rq1 = create1(); cout << "請輸入進程2的信息:" << endl; rq2 = create2(); /* cout << "遍歷進程1的信息:" << endl; see1(rq1); cout << "遍歷進程2的信息:" << endl; see2(rq2); sort(rq2); cout << "排序后進程2的信息:" << endl; see2(rq2);*/ cout << "隊列rq1運行完畢,花費的時間為:" << endl;; fun1(rq1); cout << endl; cout << "隊列rq2運行完畢,花費的時間為:" << endl; fun2(rq2); cout << endl; return 0; }
運行結果:

!!!!!!說一個令人自閉的事!!!!!!
這個程序我調了好久,經常因為死循環的問題,輸出不出來結果,真的快自閉了。。。
從開始打斷點慢慢調試的時候,找到卡住死循環的位置,慢慢改,終於改好了。
還是要有耐心啊!!!
不早啦,早點睡覺吧!晚安!
