操作系统进程调度之多级反馈队列算法模拟实现

来源:互联网 发布:音乐消原唱软件 编辑:程序博客网 时间:2024/06/04 19:28

进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;}


结果截图见最顶上

0 0
原创粉丝点击