实验五 使用动态优先权的进程调度算法模拟
1、实验目的
通过动态优先权算法的模拟加深对进程概念进程调度过程的理解。
2、实验内容
(1)用C语言来实现对N个进程采用动态优先权优先算法的进程调度。
(2)每个用来标识进程的进程控制块PCB用结构来描述,包括以下字段:
•••• 进程标识数 ID。
•••• 进程优先数 PRIORITY,并规定优先数越大的进程,其优先权越高。
•••• 进程已占用的CPU时间CPUTIME。
•••• 进程还需占用的CPU时间ALLTIME。当进程运行完毕时,ALLTIME变为0。•••• 进程的阻塞时间STARTBLOCK,表示当进程再运行STARTBLOCK个时间片后,将进入阻塞状态。
•••• 进程被阻塞的时间BLOCKTIME,表示已足赛的进程再等待BLOCKTIME个时间片后,将转换成就绪状态。
•••• 进程状态START。
•••• 队列指针NEXT,用来将PCB排成队列。
(3)优先数改变的原则:
•••进程在就绪队列中呆一个时间片,优先数加1。
•••进程每运行一个时间片,优先数减3。
(4)假设在调度前,系统中有5个进程,它们的初始状态如下:
(3) 为了清楚的观察各进程的调度过程,程序应将每个时间片内的情况显示出来,参照的具体格式如下:
RUNNING PROG:i
READY-QUEUE:-〉id1-〉id2
BLOCK-QUEUE:-〉id3-〉id4
#include <iostream>
#include <vector>
using namespace std;
//定义进程控制块
struct PCB{
int Id;
int Priority; //优先权
int CPU_time; //已占用的cpu时间片
int All_time; //还需要的时间
int Start_block; //运行多少个时间片之后开始进入Block_time
int Block_time; //阻塞的时间
int State; // 状态 0为就绪 1为阻塞 2为完成
};
//给进程控制块赋值
struct PCB p[5]=
{
{0,9,0,3,2,3,0},
{1,38,0,3,-1,0,0},
{2,30,0,6,-1,0,0},
{3,29,0,3,-1,0,0},
{4,0,0,4,-1,0,0}
};
//容器,当作队列用
vector<PCB> ready_queue;//就绪队列
vector<PCB> block_queue;//阻塞队列
vector<PCB> finish_queue;//结束队列
//输出函数
void print(){
cout<<"running prog:"<<ready_queue[0].Id<<endl;
cout<<"ready_queue:";
for(int i=0;i<ready_queue.size();i++){
cout<<"-> "<<ready_queue[i].Id;
}
cout<<endl;
cout<<"block_queue:";
for(int i=0;i<block_queue.size();i++){
cout<<"-> "<<block_queue[i].Id;
}
cout<<endl;
cout<<"id\t prio\t cpu_time\t all_time\t ";
cout<<"start_block\t block_time\t state"<<endl;
for(int i=0;i<5;i++){
if(!ready_queue.empty()){
for(int a=0;a<ready_queue.size();a++){
if(ready_queue[a].Id==i){
cout<<ready_queue[a].Id<<"\t"<< ready_queue[a].Priority<<"\t" <<"\t"<<ready_queue[a].CPU_time<<"\t";
cout<<"\t"<<ready_queue[a].All_time<<"\t"<<"\t"<<ready_queue[a].Start_block<<"\t"<<"\t"<<ready_queue[a].Block_time<<"\t"<<"\t"<<ready_queue[a].State<<endl;
break;
}
}
}
if(!block_queue.empty()){
for(int b=0;b<block_queue.size();b++){
if(block_queue[b].Id==i){
cout<<block_queue[b].Id<<"\t"<< block_queue[b].Priority<<"\t" <<"\t"<<block_queue[b].CPU_time<<"\t";
cout<<"\t"<<block_queue[b].All_time<<"\t"<<"\t"<<block_queue[b].Start_block<<"\t"<<"\t"<<block_queue[b].Block_time<<"\t"<<"\t"<<block_queue[b].State<<endl;
break;
}
}
}
if(!finish_queue.empty()){
for(int c=0;c<finish_queue.size();c++){
if(finish_queue[c].Id==i){
cout<<finish_queue[c].Id<<"\t"<< finish_queue[c].Priority<<"\t"<<"\t"<<finish_queue[c].CPU_time<<"\t";
cout<<"\t"<<finish_queue[c].All_time<<"\t"<<"\t"<<finish_queue[c].Start_block<<"\t"<<"\t"<<finish_queue[c].Block_time<<"\t"<<"\t"<<finish_queue[c].State<<endl;
break;
}
}
}
}
}
//没一个时钟脉冲之后,就对就绪队列的内容重新排序
void sortqueue(){
//ready_queue里面还有进程控制块吗?有或者没有
if( (ready_queue.empty())&&(block_queue.empty()) )
return;
else{
for(int i=0;i<ready_queue.size()-1;i++){
for(int j=i+1;j<ready_queue.size();j++){
if(ready_queue[i].Priority < ready_queue[j].Priority){
swap(ready_queue[i],ready_queue[j]); //冒泡算法,swap交换函数
}
}
}
}
}
//执行函数,其实是执行的就是就绪队列的第一个单元,
//执行相当于对第一个元素的某些值进行加减。
void run(){
if(!ready_queue.empty()){ //就绪队列没空
ready_queue[0].Priority-=3;
ready_queue[0].CPU_time++;
ready_queue[0].All_time--;
//除了执行进程以外的进程优先权加1
for(int i=1;i<ready_queue.size();i++)
ready_queue[i].Priority+=1;
//已阻塞的进程再等待Block_time个时间片后,将转换成就绪状态。
if(!block_queue.empty()){
for(int i=0;i<block_queue.size();i++){
block_queue[i].Block_time--;
if(block_queue[i].Block_time==0){
block_queue[i].State=0;//就绪
ready_queue.push_back(block_queue[i]);
block_queue.erase(block_queue.begin()+i);
}
}
}/*至此,是一个时间片对于某些因素的改变,至于是否到了队列变换的时候,下方再去判断*/
//全部遍历一遍,是否需要去阻塞
for(int i=0;i<ready_queue.size();i++){
if(ready_queue[i].Start_block>0){
ready_queue[i].Start_block--;
//去阻塞
if(ready_queue[i].Start_block==0){
ready_queue[i].State=1;//状态为1 阻塞
block_queue.push_back(ready_queue[i]);
ready_queue.erase(ready_queue.begin()+i);
}
}
}
//没有执行时间,调入到结束队列
if(ready_queue[0].All_time<=0){
ready_queue[0].State=2;//状态为2 结束
finish_queue.push_back(ready_queue[0]);// push_back最后一个向量后插入一个元素
ready_queue.erase(ready_queue.begin()+0);//删除第0个元素,并将后面的前移一位
}
}
}
int main(){
//将所有的pcb输入到就绪队列里面,再去排序
for(int i=0;i<5;i++){
ready_queue.push_back(p[i]);
}
int num=1;
for(;!ready_queue.empty();){
cout<<num++<<"--------------------实时状态------------------------"<<endl;
sortqueue();
run();
print();
cout<<endl<<endl;
}
cout<<"运行完成"<<endl<<"运行时序为";
for(int i=0;i<5;i++)
{
cout<<finish_queue[i].Id;
}
return 0;
}