#include <iostream>
using namespace std;
enum Status{running,ready,finish};//定义枚举常量存放进程状态
enum Policy{fifo,hpf,rr};//枚举常量存放调度方式
/*定义PCB类,结构为进程标识ID,优先权priority,进程已运行时间cputime,还需要运行时间alltime,状态变量state*/
typedef class PCB
{
public:
int id,priority,cputime,alltime;//定义进程标识id,优先权priority,进程已运行时间cputime,还需要运行时间alltime
Status state;//定义状态变量state
class PCB *next;//定义PCB类指针*next,用来指向PCB链表的下一个元素
PCB()//PCB类的构造函数初始化优先权为0
{
priority=0;
}
}PCB,*PCBptr,**PCBpp;
//两个全局变量
char x;
PCBpp pp;
/*打印head为头指针的PCB链表信息*/
void Print(PCBptr head)
{
PCBptr p;//定义PCB类指针p
cout<<"\n运行队列:";
for(p=head;p->next;p=p->next)
{
if(p->next->state==running)//如果指针指向的下一个进程是执行状态,
{
cout<<"ID"<<p->next->id;//则将进程号输出到执行态队列。
break;
}
}
cout<<"\n就绪队列:";
for(p=head;p->next;p=p->next)
if(p->next->state==ready)//输出就绪状态进程ID
cout<<"ID"<<p->next->id<<' ';
cout<<"\n---------------------------------------------------------------\n"
<<" \t进程号\t优先数\t 已运行时间\t还需要时间\t状态\n";
for(p=head;p->next;p=p->next)//依次输出id,priority,cputime,alltime.state信息
{
cout<<"\t "<<p->next->id<<"\t "<<p->next->priority<<"\t "<<p->next->cputime<<"\t\t "<<p->next->alltime<<"\t";
switch(p->next->state)
{
case ready:cout<<"\t就绪";break;
case running:cout<<"\t运行";break;
default:exit(0);
}
cout<<'\n';
}
cout<<"---------------------------------------------------------------\n"
<<"按任意键并回车继续...";
cin>>x;
}
/*删除以head为头指针的PCB链表中p所指向的结点*/
void Delete(PCBptr head,PCBptr p)
{
PCBptr q=head;
while(q->next!=p) q=q->next;//利用q指针从head开始依次查找,直到q->next为p指针
q->next=p->next;//将p指针的后一个结点信息连接到q->next
delete p;//删除p所指向的结点
}
/*动态优先权算法中对就绪队列排序*/
void InsertSort(PCBpp Rdy,PCBpp RdyEd,Policy algthm)
{
if(*(Rdy+1))//若就绪队列不为空(Rdy初始为就绪队列头指针)
if(RdyEd-1!=Rdy+1)//若Ready+1队列中不只一个
{
if((*(RdyEd-1))->priority>(*(RdyEd-2))->priority)//从最后一个进程开始选择一个优先权较大的进程
{
PCBpp tt;
*Rdy=*(RdyEd-1);
*(RdyEd-1)=*(RdyEd-2);
for(tt=RdyEd-3;(*Rdy)->priority>(*tt)->priority;tt--)//由后往前检索直至找到比当前进程优先权大的进程
*(tt+1)=*tt;
*(tt+1)=*Rdy;//将进程插入比当前优先权大的进程后面
}
}
}
/*就绪态转为运行态模块*/
void RdyToRun(PCBpp &Rdy,PCBpp Run,Policy algthm)
{
if(algthm==hpf)//动态优先权
{
if(*(Rdy+1))
{
(*(Rdy+1))->state=running;//将状态改为运行
*Run=*(Rdy+1);//放入执行队列
Rdy++;
}
}
else//先来先服务,轮转法
{
if(*Rdy)
{
(*Rdy)->state=running;//将状态改为运行
*Run=*Rdy;//放入执行队列
Rdy++;
}
}
}
/*运行态转为就绪态模块*/
void RunToRdy(PCBpp Run,PCBpp Rdy,PCBpp &RdyEd,Policy algthm)
{
(*Run)->state=ready;//状态改为就绪态
*RdyEd=*Run;//插入就绪队列末尾
RdyEd++;//就绪队列长度加1
if(algthm==hpf)
InsertSort(Rdy,RdyEd,algthm);//优先权算法需对就绪队列进行优先权排序
}
int main()
{
cout<<"*******************进程调度*******************\n请输入并发执行的进程个数:";
int n;
if(!(cin>>n)) {cerr<<"错误:输入不正确!"; exit(0);}
PCBptr Listhead,Listp,Listq;
Listhead=new PCB; //创建新PCB
Listp=Listhead;
for(int i=0;i<=n-1;i++) //建立n个PCB的队列。
{
Listq=new PCB;
Listp->next=Listq;
Listp=Listq;
}
Listp->next=0;
Policy algorithm;
int num1,num2;
L1: cout<<"\n请选择算法(0、先来先服务 1、动态优先权 2、轮转法):";
if(!(cin>>num1)) {cerr<<"错误:输入不正确!"; exit(0);}
algorithm=Policy(num1);//从枚举数组中提取所选择的算法
if(algorithm!=fifo&&algorithm!=hpf&&algorithm!=rr)
{cout<<"无效的算法不正确!请重新输入:\n"; goto L1;}
Listp=Listhead->next;
for(i=0;i<=n-1;i++)
{
cout<<"初始化"<<i<<"号进程的PCB:\n";//初始化当前进程优先数、已占用CPU时间、还需CPU时间、进程状态等信息
Listp->id=i;
if(algorithm==hpf)
{
cout<<" 优先数(值越大优先权越高):";
if(!(cin>>Listp->priority)) {cerr<<"错误:输入不正确!";exit(0);}
}
cout<<" 已占用CPU时间(以时间片为单位):";
if(!(cin>>Listp->cputime)) {cerr<<"错误:输入不正确!";exit(0);}
cout<<" 还需占用CPU时(以时间片为单位):";
if(!(cin>>Listp->alltime)) {cerr<<"错误:输入不正确!";exit(0);}
L2: cout<<" 进程状态(0、运行 1、就绪 2、阻塞):";
if(!(cin>>num2)) {cerr<<"错误:输入不正确!";exit(0);}
if(num2!=0&&num2!=1&&num2!=2) {cout<<"状态不正确!请重新输入:\n";goto L2;}
Listp->state=Status(num2);//从枚举数组中提取状态信息
Listp=Listp->next;
}
PCBpp Run=new PCBptr();
PCBpp Ready=new PCBptr[100];
for(i=0;i<=99;i++) *(Ready+i)=0; //初始化就绪队列
PCBpp ReadyEnd=Ready;
if(algorithm==hpf) ReadyEnd++;//如果是动态优先权算法,尾指针指向最后一个进程之后
for(Listp=Listhead;Listp->next;Listp=Listp->next)//把初始化的各个进程插入各自队列
{
switch(Listp->next->state)
{
case running:*Run=Listp->next;break;//若状态为运行态则插入运行队列
case ready:
{
*ReadyEnd=Listp->next;ReadyEnd++;//若状态为就绪态,则插入就绪队列,并将长度加1
if(algorithm==hpf)//若为动态优先权算法,则需对就绪队列进行优先权排序
InsertSort(Ready,ReadyEnd,algorithm);
break;
}
}
}
cout<<"\n程序开始并发执行,任意键并回车继续...\n\n";
cin>>x;
for(int time=1;Listhead->next;time++)//开始并发执行
{
cout<<"\n第"<<time<<"个时间片:";
if(*Run)//运行队列的变化
{
if(algorithm==hpf)
(*Run)->priority-=3;//经过一个时间片后,优先数减3
(*Run)->cputime++;//已经运行时间加1
if((*Run)->alltime>0)
(*Run)->alltime--;//对所有尚未完成的进程,还需CPU时间减1
}
if(algorithm==hpf)//就绪队列的变化
{
if(*(Ready+1))//就绪队列中未调度的进程,一个时间片后优先权+1
for(pp=Ready+1;pp!=ReadyEnd;pp++)
(*pp)->priority++;
}
Print(Listhead);//打印当前时间片结束后的进程信息
if(*Run)
{
if((*Run)->alltime==0)
{//如果运行完毕,把该进程撤销,并拿就绪队列首部的进程来运行
Delete(Listhead,*Run);
RdyToRun(Ready,Run,algorithm);
}
else//若进程尚未运行完毕
{
/*动态优先权算法调度模块*/
if(algorithm==hpf)
{//在动态优先权算法下,比较现在运行的进程的优先权和*(Ready+1)的优先权的大小。
if(*(Ready+1))
if((*Run)->priority<(*(Ready+1))->priority)
{
(*Run)->state=ready;//将当前运行进程放入就绪队列
*ReadyEnd=*Run;ReadyEnd++;//就绪队列长度加1
InsertSort(Ready,ReadyEnd,algorithm);//对就绪队列优先权排序
if(*(Ready+1))
{
(*(Ready+1))->state=running;//将*(Ready+1)进程加入运行队列
*Run=*(Read
Cherish
- 粉丝: 14
- 资源: 8
最新资源
- DomainException(解决方案).md
- InvalidArgumentException(解决方案).md
- PenSessionExpiredException解决办法.md
- LengthException(解决方案).md
- java.工具链.md
- InvalidPenSessionStateException解决办法.md
- PenSyncFailureException解决办法.md
- java.Gradle.md
- java.Git版本控制.md
- java.Maven.md
- PharException(解决方案).md
- PenStorageFullException解决办法.md
- java.Lombok.md
- ReflectionException(解决方案).md
- RangeException(解决方案).md
- java.测试.md
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈