模拟进程调度
来源:互联网 发布:2016年淘宝卖什么最好 编辑:程序博客网 时间:2024/05/30 07:12
通过C++编程来模拟三种进程调度方式:FCFS(先来先服务),Priority Scheduling(优先度调度)和Multilever feedback queue (多级反馈队列)
现有5个进程同时一次进入进程调度器
进程名时间花销优先度P1103P211P323P414P552多级反馈队列中,第一级的时间片是1,第二级是2.....以此类推
模拟进程调度程序说明
两个结构
首先介绍两个数据结构
Process结构:
structProcess
{
char name[NAME_LENGTH];//进程名字
int priority;//优先度
int cost;//进程执行需要时间开销
int used;//已用时间
int wait_time;//等待时间
Process(char na[],int ct,int prio)
{
strcpy(name,na);
cost = ct;
priority = prio;
wait_time = 0;
used = 0;
}
void print()
{
printf("Process Name:%s \tPriorityValue:%d \tWaiting time:%d\n",name,priority,wait_time);
}
};
这个结构用来保存进程信息。
然后通过创建一个Process指针数组来保存要处理的进程
Process *process_list[PROCESS_NUM];
process_list[0]=newProcess("P1",10,3);
process_list[1]=newProcess("P2",1,1);
process_list[2]=newProcess("P3",2,3);
process_list[3]=newProcess("P4",1,4);
process_list[4]=new Process("P5",5,2);
MultiQueue结构:
struct MultiQueue
{
queue<Process *> plist;//该级的队列
int quantum_time;//该级别的时间片
int lever;//记录级别
MultiQueue *next;//下一级队列
MultiQueue()
{
lever = 0;
next = NULL;
quantum_time = 0;
while(!plist.empty())
plist.pop();
}
};
这个多级队列结构是服务于多级反馈队列进程调度服务的。
一个MultiQueue就是一个多级反馈队列。
quantum_time定义了该级别的时间片
plist则是保存了在这个级别队列里面的待运行进程
lever记录当前是第几个级别的
三个方法
由于要模拟先到先服务(FIFO/FCFS)、优先数调度(Priority Scheduling)和多级反馈队列调度(Multilevel feedback queue),所以我实现了三个方法分别表示这三种调度方法,每一个方法的参数都是待调度进程数组和数组规模。也就是上文利用Process创建的指针数组Process *process_list[PROCESS_NUM].
First Come,First Served方法
//First Come,First Served 先来先服务 ,即FIFO,First In,First Out
void FCFS(Process* plist[],int psize)
{
printf("First Come First Served running...\n");
queue< Process * > fcfs_list;
while(!fcfs_list.empty())fcfs_list.pop();
for (int i=0;i<psize;i++)
{
fcfs_list.push(plist[i]);
}
int time =0;
while(!fcfs_list.empty())
{
Process * excu = fcfs_list.front();
fcfs_list.pop();
excu->wait_time = time;
time += excu->cost;
printf("%s excute %d timeunits...\n",excu->name,excu->cost);
}
printf("First Come First Served ending...\n");
time = 0;
for (int i=0;i<psize;i++)
{
plist[i]->print();
time += plist[i]->wait_time;
}
double mwt = (double)time/psize;
printf("Mean Waiting Time is %.2lf\n",mwt);
printf("------------------------\n");
}
首先创建一个队列fcfs_list表示FCFS的待执行进程。然后按照plist[]的顺序把进程压进fcfs_list里面。接着就开始执行进程。
每次执行从fcfs_list取出最前面的进程,此时时间累加器time即为此进程的等待时间,并把该进程的执行时间累加紧time里面。一直执行直到fcfs_list为空。
这时每一个进程任务都已经执行完毕了,最后可以通过访问每一个进程的plist[i]->wait_time来得到平均等待时间并打印出来
Priority Scheduling方法
//Priority Scheduling优先数调度法,非抢占式
void PS(Process* plist[],int psize)
{
printf("Priority Scheduling running...\n");
//因为优先度调度需要根据优先度对进程进行排序后放进队列,为了不影响原顺序,用一个新的数组来暂存排序结果
Process* sort_list[PROCESS_NUM];
for (int i=0;i<psize;i++)
{
sort_list[i] = plist[i];
}
sort_priority(sort_list,psize);
queue< Process * > ps_list;
while(!ps_list.empty())
ps_list.pop();
for (int i=0;i<psize;i++)
{
ps_list.push(sort_list[i]);
}
int time =0;
while(!ps_list.empty())
{
Process * excu = ps_list.front();
ps_list.pop();
excu->wait_time = time;
time += excu->cost;
printf("%s excute %d timeunits...\n",excu->name,excu->cost);
}
printf("Priority Scheduling ending...\n");
time = 0;
for (int i=0;i<psize;i++)
{
plist[i]->print();
time += plist[i]->wait_time;
}
double mwt = (double)time/psize;
printf("Mean Waiting Time is %.2lf\n",mwt);
printf("------------------------\n");
}
由于优先数调度是根据每一个进程的优先数来判定进程的执行顺序,优先数越小,越早执行。
所以要先对进程进行一个优先数升序排序。为了不影响原进程数组的顺序。这里新建了一个plist[]的副本sort_list[],然后对sort_list[]进行升序排序,最后把sort_list[]排序后的结果按顺序压进优先数调度队列ps_list里面。
接着就开始执行进程。
每次执行从ps_list取出最前面的进程,此时时间累加器time即为此进程的等待时间,并把该进程的执行时间累加紧time里面。一直执行直到ps_list为空。
这时每一个进程任务都已经执行完毕了,最后可以通过访问每一个进程的plist[i]->wait_time来得到平均等待时间并打印出来
Multilevel feedback queue方法
//Multilevel feedback queue多级反馈队列调度
void MFQ(Process* plist[],int psize)
{
printf("Multilevel feedback queue running...\n");
MultiQueue *mq = new MultiQueue();
MultiQueue *current;
mq->quantum_time = 1;
mq->lever = 1;
for (int i=0;i<psize;i++)
{
plist[i]->used = 0;
mq->plist.push(plist[i]);
}
int time = 0;
current = mq;
//只有没有下一级队列并且当前队列为空时,才退出
while(! (current->plist.empty() && current->next==NULL))
{
if (current->plist.empty())
current = current->next;
else
{
Process * excu = current->plist.front();
current->plist.pop();
int todo_time = excu->cost - excu->used;
if (todo_time > current->quantum_time )
{
todo_time =current->quantum_time;
excu->used += todo_time;
if (current->next==NULL)
{
current->next = newMultiQueue();
current->next->quantum_time = current->quantum_time+1;
current->next->lever= current->lever+1;
}
current->next->plist.push(excu);
}else
{
excu->wait_time = time -excu->used;
excu->used += todo_time;
}
time += todo_time;
printf("%s excute %d time units at %dlayer...\n",excu->name,todo_time,current->lever);
}
}
printf("Multilevel feedback queue ending...\n");
time = 0;
for (int i=0;i<psize;i++)
{
plist[i]->print();
time += plist[i]->wait_time;
}
double mwt = (double)time/psize;
printf("Mean Waiting Time is %.2lf\n",mwt);
printf("------------------------\n");
}
多级反馈队列把进程划分到多个级别里面执行,每一个级别的队列给与进程有限的运行时间,若所给时间内还没有执行完毕,则弹出此进程并把此进程放置到下一级进程里面继续执行。
而一般下一级队列要比上一级队列的能给与时间片要长。也就是说,如果第一级队列的时间片为1,时间片时间内不能完成,则弹到第二级队列执行,第二级的队列时间片可能就为2,以此类推。
在MFQ方法里面也是这么运作的。首先创建一个多级队列MultiQueue *mq = new MultiQueue(),用MultiQueue *current指示当前级别队列。一开始把所有进程压进mq->plist里面,也就是压进第一级的队列里面。然后开始执行进程
每执行一个进程,首先判断该进程还需要执行的时间能否在当前级别的时间片内完成,能完成则该进程的等待时间为excu-> wait_time = 当前时间time-该进程已用时间excu->used ;若是不能在该时间片内完成,则把此进程使用世家加上该级别的时间片世家todo_time = current->quantum_time;excu->used += todo_time;由于此进程仍需要执行,需要压进下一级的队列里面待执行,所以先检查下一级队列是否存在,不存在则创建下一级队列,然后压进下一级队列里面。
以上操作完成了就表示该进程在此级别里面的操作结束了。把该进程的使用时间todo_time 加到时间累加器time里面表示时间的使用time += todo_time;
一直重复这操作直到该级别的队列为空。若是下一级别队列不为空,则把当前队列指针移到下一级队列里面if (current->plist.empty()) current = current->next; 否则就表示所有进程都执行完毕了。
最后可以通过访问每一个进程的plist[i]->wait_time来得到平均等待时间并打印出来
附录
源代码
//Process Scheduling (Simulation)/*author:黎伟杰*/#include <iostream>#include <cstdio>#include <cstring>#include <queue>#include <algorithm>using namespace std;#define NAME_LENGTH 255#define PROCESS_NUM 5struct Process{ char name[NAME_LENGTH];//进程名字 int priority;//优先度 int cost;//进程执行需要时间开销 int used;//已用时间 int wait_time;//等待时间 Process() { wait_time = 0; used = 0; } Process(char na[],int ct,int prio) { strcpy(name,na); cost = ct; priority = prio; wait_time = 0; used = 0; } Process(Process &rhs) { strcpy(name,rhs.name); cost = rhs.cost; priority = rhs.priority; wait_time = rhs.wait_time; used = rhs.used; } void init(char na[],int ct,int prio) { strcpy(name,na); cost = ct; priority = prio; wait_time = 0; used = 0; } void print() { printf("Process Name:%s \tPriority Value:%d \tWaiting time:%d\n",name,priority,wait_time); }};void sort_priority(Process* plist[],int psize){ int i = psize-1; Process *tmp; while(i>=0) { for (int j=0;j<i;j++) { if (plist[i]->priority<plist[j]->priority) { tmp = plist[i]; plist[i] = plist[j]; plist[j] = tmp; } } i--; }}//First Come,First Served 先来先服务 ,即FIFO,First In,First Outvoid FCFS(Process* plist[],int psize){ printf("First Come First Served running...\n"); queue< Process * > fcfs_list; while(!fcfs_list.empty())fcfs_list.pop(); for (int i=0;i<psize;i++) { fcfs_list.push(plist[i]); } int time =0; while(!fcfs_list.empty()) { Process * excu = fcfs_list.front(); fcfs_list.pop(); excu->wait_time = time; time += excu->cost; printf("%s excute %d time units...\n",excu->name,excu->cost); } printf("First Come First Served ending...\n"); time = 0; for (int i=0;i<psize;i++) { plist[i]->print(); time += plist[i]->wait_time; } double mwt = (double)time/psize; printf("Mean Waiting Time is %.2lf\n",mwt); printf("------------------------\n");}//Priority Scheduling优先数调度法,非抢占式void PS(Process* plist[],int psize){ printf("Priority Scheduling running...\n"); //因为优先度调度需要根据优先度对进程进行排序后放进队列,为了不影响原顺序,用一个新的数组来暂存排序结果 Process* sort_list[PROCESS_NUM]; for (int i=0;i<psize;i++) { sort_list[i] = plist[i]; } sort_priority(sort_list,psize); queue< Process * > ps_list; while(!ps_list.empty()) ps_list.pop(); for (int i=0;i<psize;i++) { ps_list.push(sort_list[i]); } int time =0; while(!ps_list.empty()) { Process * excu = ps_list.front(); ps_list.pop(); excu->wait_time = time; time += excu->cost; printf("%s excute %d time units...\n",excu->name,excu->cost); } printf("Priority Scheduling ending...\n"); time = 0; for (int i=0;i<psize;i++) { plist[i]->print(); time += plist[i]->wait_time; } double mwt = (double)time/psize; printf("Mean Waiting Time is %.2lf\n",mwt); printf("------------------------\n");}//多级队列,用链表实现struct MultiQueue{ queue<Process *> plist;//该级的队列 int quantum_time;//该级别的时间片 int lever;//记录级别 MultiQueue *next;//下一级队列 MultiQueue() { lever = 0; next = NULL; quantum_time = 0; while(!plist.empty()) plist.pop(); }};//Multilevel feedback queue多级反馈队列调度void MFQ(Process* plist[],int psize){ printf("Multilevel feedback queue running...\n"); MultiQueue *mq = new MultiQueue(); MultiQueue *current; mq->quantum_time = 1; mq->lever = 1; for (int i=0;i<psize;i++) { plist[i]->used = 0; mq->plist.push(plist[i]); } int time = 0; current = mq; //只有没有下一级队列并且当前队列为空时,才退出 while(! (current->plist.empty() && current->next==NULL)) { if (current->plist.empty()) current = current->next; else { Process * excu = current->plist.front(); current->plist.pop(); int todo_time = excu->cost - excu->used; if (todo_time > current->quantum_time ) { todo_time = current->quantum_time; excu->used += todo_time; if (current->next==NULL) { current->next = new MultiQueue(); current->next->quantum_time = current->quantum_time+1; current->next->lever = current->lever+1; } current->next->plist.push(excu); }else { excu->wait_time = time - excu->used; excu->used += todo_time; } time += todo_time; printf("%s excute %d time units at %d layer...\n",excu->name,todo_time,current->lever); } } printf("Multilevel feedback queue ending...\n"); time = 0; for (int i=0;i<psize;i++) { plist[i]->print(); time += plist[i]->wait_time; } double mwt = (double)time/psize; printf("Mean Waiting Time is %.2lf\n",mwt); printf("------------------------\n");}int main(){ Process *process_list[PROCESS_NUM]; process_list[0]=new Process("P1",10,3); process_list[1]=new Process("P2",1,1); process_list[2]=new Process("P3",2,3); process_list[3]=new Process("P4",1,4); process_list[4]=new Process("P5",5,2); FCFS(process_list,5); PS(process_list,5); MFQ(process_list,5); return 0;}
- 进程调度模拟程序
- 进程调度模拟
- 模拟进程调度
- 进程调度模拟
- 进程调度模拟算法
- 模拟设计进程调度
- 进程调度模拟
- 模拟进程调度
- 模拟进程调度
- 模拟进程调度
- 模拟进程调度算法
- 进程调度模拟
- 处理机进程调度模拟
- C 模拟进程调度
- 进程调度模拟算法
- 进程调度模拟
- 【进程调度】模拟进程调度的过程
- 操作系统进程调度模拟程序
- ASP.NET Trace 使用
- Oracle基础——第四章 用户管理及表空间
- Java之关键字和保留字
- Ubuntu下ndk-build编译C++出错:non-numeric second argument to `wordlist' function: '
- 我的编程学习之路
- 模拟进程调度
- Android开发环境搭建
- static class 静态类
- 输入输出流
- 混“钝”职场
- javacard 临时对象 永久对象
- 一种Playfair密码变种加密方法如下:首先选择一个密钥单词(称为pair)(字母不重复,且都为小写字母),然后与字母表中其他字母一起填入至一个5x5的方阵中,填入方法如下:
- 汉诺塔问题
- 一个经典实用的 IPtables Shell 脚本