实验一 进程调度
实验学时:3 学时
实验类型:设计
实验要求:必修
一、 实验目的
多道程序设计中,经常是若干个进程同时处于就绪状态,必须依照某种策略来
决定那个进程优先占有处理机。因而引起进程调度。本实验模拟在单处理机情况下
的处理机调度问题,加深对进程调度的理解。
二、 实验内容
1.优先权法、轮转法
简化假设
1) 进程为计算型的(无 I/O)
2) 进程状态:ready、running、finish
3) 进程需要的 CPU 时间以时间片为单位确定
2.算法描述
1) 优先权法——动态优先权
当前运行进程用完时间片后,其优先权减去一个常数。
2) 轮转法
三、 流程图
#include<iostream>
#include<stdlib.h>
#include<string>
#include<time.h>
using namespace std;
class PCB
{
public:
char name[20]; //进程名字
int prio; //优先级
int round; //时间片
int cputime; //进程已运行时间
int needtime; //执行剩余时间
string state; //进程状态running,ready,finish
int count; //执行次数
PCB *next;
};
PCB *ready=NULL,*running=NULL,*finish=NULL; //定义就绪执行完成队列
PCB *tial=ready; //时间片运行队列
bool PrioCreate(); //创建优先级队列函数
void Priority(); //优先级调度
bool RoundrobinCerate(); //创建轮转队列函数
void Roundrobin(); //轮转法调度
void GetFirst(); //返回队列第一个节点
void InsertPrio(PCB*in); //按优先权大小,把 n 个进程拉成一个就绪队列
void InsertFinish(PCB*in); //优先权完成队列
void Dtime(int t); //轮转时间函数
int num,m;
void GetFirst()
{
running=ready;
if(ready!=NULL)
{
running->state="running";
ready=ready->next;
running->next=NULL;
}
}
void InsertPrio(PCB *in)
{
PCB *fir,*sec;
fir=sec=ready;
if(ready==NULL) //如果队列为空成为第一个元素
{
in->next=ready;
ready=in;
}
else //寻找合适的位置插入
{
if(in->prio>fir->prio) //大于第一个优先级,则插入队头
{
in->next=ready;
ready=in;
}
else
{
while(fir->next!=NULL) //移动查找到优先级比他小得位置插入
{
sec=fir;
fir=fir->next;
}
if(fir->next==NULL) //优先级最小插入队尾
{
in->next=fir->next;
fir->next=in;;
}
else //插入队列
{
sec=in;
in->next=fir;
}
}
}
}
void InsertFinish(PCB *in)
{
PCB *fir;
fir=finish;
if(finish==NULL)
{
in->next=finish;
finish=in;
}
else
{
while(fir->next!=NULL)
{
fir=fir->next;
}
in->next=fir->next;
fir->next=in;
}
}
bool PrioCreate() //创建优先级队列函数
{
PCB *Node;
for(int i=0;i<num;i++)
{
Node=new PCB;
if(Node==NULL)
return false;
else
{
cout<<"请输入进程名称"<<endl;
cin>>Node->name;
Node->needtime=rand()%20+1;
Node->prio=rand()%10+1;
Node->cputime=0;
Node->state="ready";
Node->count=0;
}
InsertPrio(Node);
}
}
void PrintPr()
{
cout<<"进程名称"<<"\t"<<"优先级"<<"\t"<<"还需要时间"<<"\t"<<"状态"<<endl;
}
void PrintPr(PCB *p)
{
cout<<p->name<<"\t\t"<<p->prio<<"\t\t"<<p->needtime<<"\t"<<p->state<<endl;
}
void DisplayPr() //输出优先级队列
{
PCB *p;
p=ready;
while(p!=NULL)
{
PrintPr(p);
p=p->next;
}
p=finish;
while(p!=NULL)
{
PrintPr(p);
p=p->next;
}
p=running;
while(p!=NULL)
{
PrintPr(p);
p=p->next;
}
cout<<"----------------------------------------\n";
}
void Priority() //优先级调度
{
int N=1;
GetFirst();
PrintPr();
while(running!=NULL)
{
DisplayPr(); //输出队列状态
while(N)
{
running->prio=running->prio-3; //优先级减三
running->cputime++; //运行时间加一
running->needtime--; //剩余时间减一
if(running->needtime==0) //执行完毕,状态改为finish,加入完成队列
{
running->state="finish";
running->count++;
InsertFinish(running);
N=0;
}
else //状态改为ready,加入就绪队列
{
running->state="ready";
running->count++;
InsertPrio(running);
N=0;
}
}
N=1;
GetFirst(); //就绪队列第一个加入执行队列
}
}
void queue(PCB *p) //加入轮转就绪队列函数
{
if(ready==NULL)
{
p->next=NULL;
ready=p;
tial=p;
}
else
{
tial->next=p;
tial=p;
p->next=NULL;
}
}
bool RoundrobinCreat() //创建轮转队列函数
{
PCB *Node;
cout<<"输入时间片"<<endl;
cin>>m;
for(int i=0;i<num;i++)
{
Node=new PCB;
if(Node==NULL)
return false;
else
{
cout<<"输入进程名称"<<endl;
cin>>Node->name;
Node->needtime=rand()%20+1;
Node->cputime=0;
Node->state="ready";
Node->count=0;
Node->round=m;
}
queue(Node);
}
return true;
}
void Dtime(int t) //轮转法运行1时间
{
time_t current_time;
time_t start_time;
do
{
time(& current_time);
} while((current_time-start_time)<t);
}
void PrintRR() //输出队列状态
{
cout<<"进程名称"<<"\t"<<"已运行时间"<<"\t"<<"还需要时间"<<"\t"<<"状态"<<endl;
}
void PrintRR(PCB * p) //输出队列状态
{
cout<<p->name<<"\t\t\t"<<p->cputime<<"\t\t"<<p->needtime<<" \t"<<p->state<<endl;
}
void DisplayRR() //输出轮转法队列
{
PCB *p;
if(running != NULL)
PrintRR(running);
Dtime(1);
p = ready;
while(p != NULL)
{
PrintRR(p);
p = p->next;
}
Dtime(1);
p = finish;
while(p != NULL)
{
PrintRR(p);
p = p->next;
}
cout<<"--------------------------------------------------------------\n";
}
void Roundrobin() //轮转法调度
{
running = ready;
ready = ready->next;
running->state ="ready";
PrintRR();
while(running!=NULL) //执行队列不为空,轮转法调度
{
DisplayRR(); //输出状态
running->cputime++; //运行时间加一
running->needtime--; //剩余时间减一
running->count++; //执行次数加一
if(running->needtime == 0) //执行完成,改变进程状态,加入完成队列
{
running->state = "finish";
running->next = finish;
finish = running;
running = NULL;
if(ready!=NULL)
{
running = ready;
running->state = "running";
ready = ready->next;
}
}
else if(running->count == running->round) //执行时间等于时间片,改变进程状态 ,加入就绪队列
{
running->count = 0;
running->state = "ready";
queue(running);
running=NULL;
if(ready!=NULL)
{
running = ready;
running->state = "running";
ready = ready->next;
}
}
}
}
int main()
{
char chose;
cout<<"请输入进程数目"<<endl;
cin>>num;
cout<<"请选择调度方法(Y/N)"<<endl;
cin>>chose;
switch(chose)
{
case 'Y':
PrioCreate();
Priority();
break;
case 'N':
RoundrobinCreat();
Roundrobin();
break;
default:
break;
}
return 0;
}