实验一 处理机调度实验
一、 实验目的:
用高级语言编写和调试一个进程调度程序,以加深对进程的概念及进程调度算法的理解。
二、 实验要求:
用C++语言实验对N个进程采用非抢占式的动态优先权优先算法的进程调度
三、 实验内容:
(1) 设计一个有N个进程并发的进程调度程序。进程调度算法:采用最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)算法。
(2) 每个进程有一个进程控制块(PCB)表示。PCB用结构来描述,包括以下字段:
l 进程标识ID、
l 优先数,为初始设定的模拟条件
l 到达时间,为初始设定的模拟条件
l 需要运行时间,为初始设定的模拟条件
l 已用CPU时间,为初始设定的模拟条件
l 进程阻塞时间startblock(表示进程在运行startblock个时间片后,进程将进入阻塞状态),为初始设定的模拟条件
l 进程被阻塞的时间blocktime(表示进程等待blocktime个时间片后,将转换成就绪状态),为初始设定的模拟条件,模拟执行I/O操作需要的时间
l 进程状态state,就绪W(Wait)、运行R(Run)、或完成F(Finish)三种状态
l 队列指针next等等。
(3) 优先数改变的规则
进程在就绪队列中呆一个时间片,优先数增加1;
进程每运行一个时间片,优先数减3;
(4) 运行过程描述
首先按照初始化输入,按照各进程优先级高低排列就绪队列中进程顺序,优先级最高的进程最先获得CPU控制权运行。如果运行一个时间片后,进程的已占用CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,此时应将进程的优先数减3(即降低一级),如果到了进程需被阻塞的时间点,阻塞进程,然后把它插入阻塞队列,等待经过blocktime后,再唤醒进程,把它按照优先级高低,插入就绪队列相应位置等待CPU。
每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的PCB,以便进行检查。
重复以上过程,直到所要进程都完成为止。
备注:进程的优先数及需要的运行时间可以事先人为地指定(也可以由随机数产生)。
进程的到达时间为进程输入的时间或顺序。
参考资料:
部分数据结构说明:
struct pcb { /* 定义进程控制块PCB */
char name[10];
char state;
int super;
int ntime;
int rtime;
。。。。。。。。。。。。。。。
struct pcb* link;
};
代码:
#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<stdio.h>
#include<queue>
using namespace std;
typedef struct PCB{
int Id;//进程标识
int Number;//优先数
int ArrivedTime;//到达时间
int NeedTime;//需要运行时间
int UserTime;//已用CPU时间
int BlockTime;//进程被阻塞的时间
int StartblockTime;//进程阻塞时间
char stat[6];//进程状态
int True;//标志是否运行结束
int TrueZuse;
int InZuSeTime;
};
//定义优先队列排序
bool operator < (PCB n1,PCB n2)
{
return n1.Number<n2.Number;//最大优先
}
PCB pcb[50];
priority_queue<PCB> q;//就绪队列
priority_queue<PCB> Q;//阻塞队列
int AllTime=0;
int INFI=3;
//将进程插进就绪队列
void insertq(){
for (int i=0; i<INFI; i++){
//判断是否已经运行结束
if (pcb[i].True==0)
{
q.push(pcb[i]);
}
}
}
//判断是否运行结束
int IsFinish(PCB pcb)
{
if(pcb.True==1)
return 1;
else return 0;
}
//打印进程信息
void PutOut(PCB pcb)
{
printf("Id=%d\n",pcb.Id);
printf("Number=%d\n",pcb.Number);
printf("ArrivedTime=%d\n",pcb.ArrivedTime);
printf("NeedTime=%d\n",pcb.NeedTime);
printf("UserTime=%d\n",pcb.UserTime);
printf("BlockTime=%d\n",pcb.BlockTime);
printf("StartblockTime=%d\n",pcb.StartblockTime);
printf("stat=%s\n",pcb.stat);
printf("True=%d\n",pcb.True);
printf("TrueZuse=%d\n",pcb.TrueZuse);
printf("InZuSeTime=%d\n",pcb.InZuSeTime);
printf("...........下一个进程详情............\n");
}
//初始化进程
void init()
{
pcb[0].Id=0;
pcb[0].Number=8;
pcb[0].ArrivedTime=0;
pcb[0].NeedTime=3;
pcb[0].UserTime=0;
pcb[0].StartblockTime=1;
pcb[0].BlockTime=1;
pcb[0].stat[0]='w';
pcb[0].stat[1]='a';
pcb[0].stat[2]='i';
pcb[0].stat[3]='t';
pcb[0].True=0;
pcb[0].TrueZuse=0;
pcb[1].Id=1;
pcb[1].Number=10;
pcb[1].ArrivedTime=0;
pcb[1].NeedTime=4;
pcb[1].UserTime=0;
pcb[1].StartblockTime=12;
pcb[1].BlockTime=12;
pcb[1].stat[0]='w';
pcb[1].stat[1]='a';
pcb[1].stat[2]='i';
pcb[1].stat[3]='t';
pcb[1].True=0;
pcb[1].TrueZuse=0;
pcb[2].Id=2;
pcb[2].Number=5;
pcb[2].ArrivedTime=0;
pcb[2].NeedTime=2;
pcb[2].UserTime=0;
pcb[2].StartblockTime=122;
pcb[2].BlockTime=1222;
pcb[2].stat[0]='w';
pcb[2].stat[1]='a';
pcb[2].stat[2]='i';
pcb[2].stat[3]='t';
pcb[2].True=0;
pcb[2].TrueZuse=0;
}
int main()
{
init();
insertq();
int gg =0;
AllTime=1;
while(gg<7){
//if (q.size()<=0)continue;
PCB pcbb; int id=0;
pcbb = q.top();
id = pcbb.Id;
//判断进程阻塞时间是否到了
for (int i=0; i<INFI; i++)
{
if (pcb[i].UserTime == pcb[i].StartblockTime && pcb[i].TrueZuse!=1)
{
//阻塞时间到,插进阻塞队列
Q.push(pcb[i]);
pcb[i].TrueZuse=1;//标记阻塞
pcb[i].InZuSeTime=AllTime;
}
}
if (!IsFinish(pcb[id]))
pcb[id].UserTime++;
//判断是否运行结束
if (pcb[id].UserTime>=pcb[id].NeedTime)
{
pcb[id].True=1;
pcb[id].stat[0]='F';
pcb[id].stat[1]='i';
pcb[id].stat[2]='n';
pcb[id].stat[3]='i';
pcb[id].stat[4]='s';
pcb[id].stat[5]='h';
}
//减优先数
pcb[id].Number=pcb[id].Number-3;
//就绪队列中每个加1
for (int i=0; i<INFI; i++)
{
//判断是否在就绪中列中
if (pcb[i].TrueZuse==0 && pcb[i].Id!=id&&!IsFinish(pcb[i]))
{
//优先数加一
pcb[i].Number++;
}
}
if (!Q.empty())
{
//判断阻塞时间是否结束
for (int i=0; i<INFI; i++)
{
//判断是否在阻塞队列中
if (pcb[i].TrueZuse==1)
{
//判断阻塞时间是否结束
if (pcb[i].BlockTime == AllTime - pcb[i].InZuSeTime)
{
pcb[i].TrueZuse=0;
}
}
}
}
//打印所有进程信息
for (int i=0; i<INFI; i++)
{
PutOut(pcb[i]);
q.pop();
}
insertq();
gg++;
AllTime++;
printf("...........第%d时间片............\n",gg);
}
}