操作系統進程調度之多級反饋隊列算法模擬實現


進j

 

以上為結果截圖

 

進程類頭文件

/////////////////
//進程類的頭文件
////////////////
// LProcess.h#include <string.h>#include <iostream>using namespace std;//進程類class LProcess{private:int process_ID;            //進程號string process_Name;       //進程描述intexeu_time;             //進程要求的執行時間int priority;              //進程優先級int completed_time;        //進程已經獲得的時間片int TimeForCurrentQueue;   //已獲得當前隊列的時間片public://構造函數LProcess();LProcess(int id);LProcess(int id, int time, string name);// 獲得進程ID(進程號)int getId();// 設置進程ID(進程號)void setId(int id);// 設置進程描述void setProName(string name);// 讀取進程描述string getProName();// 設置進程執行時間void setExeuTime(int time);// 獲得進程執行時間int getExeuTime();// 設置進程優先級void setPriority(int pri);// 獲得進程優先級int getPriority();// 設置進程已完成的時間片void setCompleTime(int time);// 設置進程已完成的時間片int getCompleTime();//已獲得當前隊列的時間片int getTFCQ();// 設置已經獲得當前隊列的時間片void setTFCQ(int time);};


 

//進程類的實現

//LProcess.cpp
#include "LProcess.h"LProcess::LProcess(){process_ID = 0;process_Name = "Undefined";exeu_time = 1;priority = 0;completed_time = 0;TimeForCurrentQueue = 0;}//構造函數LProcess::LProcess(int id){process_ID = id;process_Name = "Undefined";exeu_time = 1;priority = 0;completed_time = 0;TimeForCurrentQueue = 0;}//構造函數LProcess::LProcess(int id, int time, string name){process_ID = id;process_Name.assign(name);exeu_time = time;priority = 0;completed_time = 0;TimeForCurrentQueue = 0;}//  獲得進程號int LProcess::getId(){return process_ID;}// 設置進程ID(進程號)void LProcess::setId(int id){process_ID = id;}// 設置進程描述void LProcess::setProName(string name){process_Name.assign(name);}// 讀取進程描述string LProcess::getProName(){return process_Name;}// 設置進程執行時間void LProcess::setExeuTime(int time){exeu_time = time;}// 獲得進程執行時間int LProcess::getExeuTime(){return exeu_time;}// 設置進程優先級void LProcess::setPriority(int pri){priority = pri;}// 獲得進程優先級int LProcess::getPriority(){return priority;}// 設置進程已完成的時間片void LProcess::setCompleTime(int time){completed_time += time;}// 設置進程已完成的時間片int LProcess::getCompleTime(){return completed_time;}//已獲得當前隊列的時間片int LProcess::getTFCQ(){return TimeForCurrentQueue;}// 設置已經獲得當前隊列的時間片void LProcess::setTFCQ(int time){TimeForCurrentQueue += time;}////////////////////////進程的測試函數//進程的測試函數//LProcess *lp1 = new LProcess(1);//LProcess *lp2 = new LProcess(2);//LProcess *lp3 = new LProcess(3);//lp1->setProName("hello");//lp1->setPriority(2);//lp1->setCompleTime(1);//lp1->setCompleTime(3);//lp1->setExeuTime(7);//cout << "名稱" << lp1->getProName() << endl;//cout << " 進程號" << lp1->getId() << endl;//cout << "進程優先級" << lp1->getPriority() << endl;//cout << "進程已經獲得的時間" << lp1->getCompleTime() << endl;;//cout << "進程要求執行的時間" << lp1->getExeuTime() << endl;


進程隊列的實現

 
// LProQueue.h
#include "LProcess.h"struct LProcessNode{int process_ID;struct LProcessNode* next;};class LProQueue{private:LProcessNode* head;     // 指向隊列首結點的指針LProcessNode* tail;     // 指向隊列最后一個結點的指針int length;// 隊列長度int quePriority;// 進程隊列優先級int queProTime;// 進程時間片public://構造函數(優先級)LProQueue();LProQueue(int pri/*隊列優先級設定*/);//出隊bool dequeue(/*LProcessNode* lpn*/);//入隊void enqueue(LProcessNode* lpn);//獲得隊列長度int getLength();//設置隊列優先級void setQuePriority(int pri);//獲得隊列優先級int getQuePriority();//設置隊列進程時間片void setQueTime(int time);//獲得隊列進程時間片int getQueTime();//獲得隊列首地址LProcessNode* getQueHead();//獲得隊列尾地址LProcessNode* getQueTail();};


 

//進程隊列的實現
//LProQueue.cpp
#include "LProQueue.h"//構造函數(優先級)LProQueue::LProQueue(){head = tail = nullptr;length = 0;quePriority = 0;}LProQueue::LProQueue(int pri/*隊列優先級設定*/){head = tail = nullptr;length = 0;quePriority = pri;}//出隊bool LProQueue::dequeue(/*LProcessNode* lpn*/){if (getLength() <= 0){return false;}else{/*lpn = head;*/head = head->next;if (head==nullptr){tail = nullptr;}length--;}return true;}//入隊void LProQueue::enqueue(LProcessNode* lpn){if (getLength() <= 0){lpn->next = nullptr;head = tail = lpn;head->next = nullptr;tail->next = nullptr;}else{/*if (getLength()==1){}*/tail->next = lpn;tail = tail->next;}length++;}//獲得隊列長度int LProQueue::getLength(){return length;}//設置隊列優先級void LProQueue::setQuePriority(int pri){quePriority = pri;}//獲得隊列優先級int LProQueue::getQuePriority(){return quePriority;}//設置隊列進程時間片void LProQueue::setQueTime(int time){queProTime = time;}//獲得隊列進程時間片int LProQueue::getQueTime(){return queProTime;}//獲得隊列首地址LProcessNode* LProQueue::getQueHead(){return head;}//獲得隊列尾地址LProcessNode* LProQueue::getQueTail(){return tail;}//////////////////(進程)隊列的測試函數// 進程隊列的測試函數//LProQueue *lpq = new LProQueue();//LProcessNode *lpn = new LProcessNode();//lpn->process_ID = lp1->getId();//cout << lpq->getLength() << endl;//cout << lpq->getQueHead() << endl;//cout << lpq->getQuePriority() << endl;//cout << lpq->getQueTail() << endl;//cout << lpq->getQueTime() << endl;//cout << "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" << endl;//lpq->enqueue(lpn);//lpq->setQuePriority(4);//lpq->setQueTime(5);//cout << lpq->getQueHead()->process_ID << endl;//cout << lpq->getLength() << endl;//cout << lpq->getQueHead()->process_ID << endl;//cout << lpq->getQuePriority() << endl;//cout << lpq->getQueTail()->process_ID << endl;//cout << lpq->getQueTime() << endl;//LProcessNode *lpn1 = new LProcessNode();//lpn1->process_ID = lp2->getId();//cout << "#################################3" << endl;//lpq->enqueue(lpn1);//lpq->setQuePriority(6);//lpq->setQueTime(7);//cout << lpq->getQueHead()->process_ID << endl;//cout << lpq->getLength() << endl;//cout << lpq->getQueHead()->process_ID << endl;//cout << lpq->getQuePriority() << endl;//cout << lpq->getQueTail()->process_ID << endl;//cout << lpq->getQueTime() << endl;//LProcessNode *lpn2 = new LProcessNode();//lpn2->process_ID = lp3->getId();//cout << "#################################3" << endl;//lpq->enqueue(lpn2);//lpq->setQuePriority(8);//lpq->setQueTime(9);//cout << lpq->getQueHead()->process_ID << endl;//cout << lpq->getLength() << endl;//cout << lpq->getQueHead()->process_ID << endl;//cout << lpq->getQuePriority() << endl;//cout << lpq->getQueTail()->process_ID << endl;//cout << lpq->getQueTime() << endl;


多級反饋算法隊列實現MFQ

//MFQ.cpp
//********************************************************************//** 創建人: larriers//** 日  期   : 2015 / 11 / 13   19:14//** 版  本   : 1.0//** 描  述   : CPU處理機調度算法——多級隊列反饋算法(Multilevel Feedback Queue,MFQ) //** 算法思想 : 1.設置N個進程隊列,不同隊列對於處理機的優先級是不相等的//**  一般來說,優先級Priority(Q1) > Priority(Q2) > ... > Priority(QN)//**2.而位於相同隊列的不同進程是具有相同優先級的,采用時間片輪轉法//**  一般來說,優先級越高的隊列它獲得CPU的時間片就越短//**  這就是這個算法的精妙之處,防止出現后來來的進程或者優先級低的進程出現飢餓現象//** 算法描述 : 1.進程在進入待調度的隊列等待時,首先進入優先級最高的Q1等待。//**2.首先調度優先級高的隊列中的進程。若高優先級中隊列中已沒有調度的進程,則調度次優先級隊列中的進程。//**              例如:Q1, Q2, Q3三個隊列,只有在Q1中沒有進程等待時才去調度Q2,同理,只有Q1, Q2都為空時才會去調度Q3。//**3.對於同一個隊列中的各個進程,按照時間片輪轉法調度。比如Q1隊列的時間片為N//**              那么Q1中的作業在經歷了N個時間片后若還沒有完成,則進入Q2隊列等待//**              若Q2的時間片用完后作業還不能完成,一直進入下一級隊列,直至完成。//**4.在低優先級的隊列中的進程在運行時,又有新到達的作業,//**              那么在運行完這個時間片后,CPU馬上分配給新到達的作業(搶占式)。//** 測  試   :1.由於在此程序的代碼實現,每個進程所需要的時間片隨即給定的,故用以下數據進行驗證//**              隊列1,給每個進程時間片為2,優先級3//**              隊列2,給每個進程時間片為4,優先級2//**              隊列3,給每個進程時間片為8,優先級1//**              進程A,0時刻到達,所需要時間片為2    完成時刻2//**              進程B,1時刻到達,所需要時間片為3    完成時刻10//**              進程C,2時刻到達,所需要時間片為5    完成時刻15//**              進程D,3時刻到達,所需要時間片為1    完成時刻7//**              進程E,4時刻到達,所需要時間片為5    完成時刻16//**因為我修改了算法的最后一步,將沒有完成的進程重新加入最后一個隊列,所以上面數據僅僅適用於進程不用重新進入隊列的情況,並且//**寫的進程是特殊情況,每個進程時間片隨即給定,所以,只有調試的時候才能看出來,或者增加一些變量//** 應  用   :   實現的隊列類和進程類加以修改可重復使用,實現進程調度//** 實現問題 :   OS中如果分到時間片的進程應該排在新到的進程后面入隊,恰好這個並不存在這個問題,搶占式短作業優先隊列存在,故應遵循這一慣例//**                 還有一個改進的地方,可以不用將每個時刻作為一次循環,為什么,這樣的話,進程多了會效率很低,但是這段程序可以描述這一思想//** 理論上,可以將有新進程進入的時候再進行檢查,或者正在執行的進程時間片結束//**                 所以應當增加監視某進程是否完成分配的時間片是否完成的boolean型變量//**************************** 修改記錄 ******************************//** 修改人 ://** 日  期 ://** 描  述 ://******************************************************************** #include <time.h>#include"LProQueue.h"//  思路花絮,,,啦啦啦啦// 注意在這段代碼中的關於進程優先級賦值的語句可以不必在意,無作用,因為進程入隊之后使用的優先級就是所在隊列的優先級// 動態生成要執行的進程數組和進程隊列,數量由用戶給定// 對於每個進程需要的時間片通過隨機函數隨機生成1-5的整數進行隨機指定// 現對於每個進程的到達時間進行假定,假定依次每個時刻到達,即1號進程(位於進程數組的下標為0的位置)//      在0時刻到達,2號(1)在時刻1到達,3號(2)在時刻2到達,依次重復// 每個隊列所獲得的時間片是通過如下方法實現:由用戶給定第一個隊列的時間片//      剩下的每個隊列的時間片均為前一個隊列的二倍// 保存每個進程的執行結果(到達時刻和完成時刻)// 還應保存當前完成了幾個進程// 設置一個信號量,記錄CPU是否在工作// 在給定數目的隊列給定長度時間片,總的時間片是一定的,則有可能出現時間片都運行完了,某些進程還未完成工作//      應保存進程是否完成的結果,這里理解錯了,應該是重新再次進入最后一個隊列重新由這個隊列進行時間片的再次分配int main(){intSYS_TIME = 0;//記錄CPU處理機的時刻bool isWork = false;intprocessNum = 0;intqueueNum = 0;intqueue_first_time = 0;int restProNum = 0;cout << "請輸入要進行作業的進程數"<<endl;cin >> processNum;restProNum = processNum;cout << "請輸入多級隊列的隊列數" << endl;cin >> queueNum;//生成保存進程完成時刻結果的數組int *processResult = new int[processNum];for (int i = 0; i < processNum; i++){processResult[i] = -1;}// 記錄進程的隨機生成的進程時間片,以便於檢驗int *process_time = new int[processNum];//動態生成用戶指定n個進程,並將為其分配進程號LProcess *process = new LProcess[processNum];for (int i = 0; i < processNum; i++){process[i].setId(i+1);process_time[i]= 1 + rand() % 5;process[i].setExeuTime(process_time[i]);}//動態生成用戶指定的n個隊列,並為其分配時間片和優先級LProQueue *queue = new LProQueue[queueNum];cout << "請指定第一級隊列的時間片" << endl;cin >> queue_first_time;queue[0].setQuePriority(queueNum);queue[0].setQueTime(queue_first_time);for (int i = 1; i < queueNum; i++){queue[i].setQuePriority(queueNum-i);queue[i].setQueTime(queue[i-1].getQueTime()*2);}// 因為這個算法是在要執行的進程都完成而作為結束標志而不是根據特定時刻// 將每個循環周期作為一個時刻while (0 != restProNum){// 將這個時刻到達的進程入到第一個隊列之中(優先級時間片短),時刻=進程號-1=進程數組中的下標if (SYS_TIME<processNum){LProcessNode *node = new LProcessNode();node->process_ID = SYS_TIME + 1;queue[0].enqueue(node);process[SYS_TIME].setPriority(queue[0].getQuePriority());}int index = -1;for (int i = 0; i < queueNum; i++){if (0!=queue[i].getLength()){index = i;break;}}int process_working=queue[index].getQueHead()->process_ID;process[process_working - 1].setCompleTime(1);process[process_working - 1].setTFCQ(1);if (process[process_working - 1].getExeuTime() == process[process_working - 1].getCompleTime()){queue[index].dequeue();processResult[process_working - 1] = SYS_TIME+1;restProNum--;}else if (queue[index].getQueTime() == process[process_working - 1].getTFCQ()){if (index == queueNum - 1){//這里不應當這么實現,為什么,應該重新進入最后一個隊列,由最后一個隊列重新分配給他時間片,所以不應該出隊,哈哈哈哈哈!!//queue[index].dequeue();//processResult[process_working - 1] = -1;//restProNum = restProNum - 1;//明白了吧LProcessNode *node1 = new LProcessNode();node1->process_ID = queue[index].getQueHead()->process_ID;node1->next = nullptr;queue[index].enqueue(node1);queue[index].dequeue();process[process_working - 1].setTFCQ(0);}else{LProcessNode *node1 = new LProcessNode();node1->process_ID = queue[index].getQueHead()->process_ID;node1->next = nullptr;queue[index + 1].enqueue(node1);queue[index].dequeue();//process[process_working - 1].setPriority(queue[index + 1].getQuePriority());process[process_working - 1].setTFCQ(0);}}SYS_TIME++;}/*for (int i = 0; i < processNum; i++){cout << processResult[i] << endl;}*/for (int i = 0; i < processNum; i++){cout <<"進程"<< i + 1 <<"        進程要求時間"<<process_time[i]<<"                   進程到達時刻"<<i<<"            完成時刻" <<processResult[i] << endl;}/*int time = rand(); int N = 1 + rand() % 10;int queNum = 0;cout << endl;*/return 0;}


結果截圖見最頂上


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com