#include <iostream>
#include <stdlib.h>
#define MAX 5
using namespace std;
enum Status{running,ready,blocked};
enum Policy{spf,rr};
typedef class PCB
{//定義PCB類。//data structure
public:
int id,cputime,alltime,startblock,blocktime;
Status state;
class PCB *next;
PCB()
{
}
}PCB,*PCBptr,**PCBpp;
PCBpp pp;//兩個全局變量
void Print(PCBptr head)
{//打印head爲頭指針的PCB鏈表信息。
PCBptr p;
cout<<"\nRunning:";
for(p=head;p->next;p=p->next)
{
if(p->next->state==running)
{
cout<<"ID"<<p->next->id;
break;
}
}
cout<<"\nReady Queue:";
for(p=head;p->next;p=p->next)
if(p->next->state==ready)
cout<<"ID"<<p->next->id<<' ';
cout<<"\nBlock Queue:";
for(p=head;p->next;p=p->next)
if(p->next->state==blocked)
cout<<"ID"<<p->next->id<<' ';
cout<<"\n-----------------------------------------------------------------------\n"
<<"|| PID ||has run || still need || when to block || block time || state\n";
for(p=head;p->next;p=p->next)
{
cout<<" "<<p->next->id<<" "<<p->next->cputime<<" "<<p->next->alltime<<" "<<p->next->startblock<<" "<<p->next->blocktime<<" ";
switch(p->next->state)
{
case ready:cout<<"ready";break;
case running:cout<<"run";break;
case blocked:cout<<"block";break;
default:exit(0);
}
cout<<'\n';
}
cout<<"------------------------------------------------------------------------\n"
<<"press any key to continue.....";
//cin>>x;
}
void Delete(PCBptr head,PCBptr p)
{//刪除以head爲頭指針的PCB鏈表中p所指向的結點。
PCBptr q=head;
while(q->next!=p) q=q->next;
q->next=p->next;
delete p;
}
void InsertSort(PCBpp Rdy,PCBpp RdyEd,Policy algthm)
{//直接插入排序。
if(*(Rdy+1))//隊列不爲空
if(RdyEd-1!=Rdy+1)
{//Ready+1隊列中不只一個。
if(algthm==spf)
{
if((*(RdyEd-1))->alltime<(*(RdyEd-2))->alltime)
{
PCBpp tt;
*Rdy=*(RdyEd-1);
*(RdyEd-1)=*(RdyEd-2);
for(tt=RdyEd-3;(*Rdy)->alltime<(*tt)->alltime;tt--)
*(tt+1)=*tt;
*(tt+1)=*Rdy;
}
}
}
}
void RunToBlk(PCBpp Run,PCBpp &BlkEd)
{//定義運行態轉爲阻塞態。
(*Run)->state=blocked;
*BlkEd=*Run;
BlkEd++;
}
void RdyToRun(PCBpp &Rdy,PCBpp Run,Policy algthm)
{//定義就緒態轉爲運行態。
if(algthm==spf)
{
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++;
if(algthm==spf)
InsertSort(Rdy,RdyEd,algthm);
}
int main()
{
cout<<"*********************starting******************\n\nhow many processes you want to create ?";
int n,i,time;
// cout<<n;
if(!(cin>>n)) {cerr<<"error"; exit(0);}
PCBptr Listhead,Listp,Listq;//建立n個
Listhead=new PCB; //
Listp=Listhead; //
for(i=0;i<=n-1;i++) //
{
Listq=new PCB; //
Listp->next=Listq; //
Listp=Listq; //
}
Listp->next=0; //PCB的隊列。
Policy algorithm;
int num1,num2;
cout<<"\ninput which algorithm to choose ,please ( SPF:0, RR:1 ) : ";
while(1){
if(!(cin>>num1)) {cerr<<"error"; exit(0);}
algorithm=Policy(num1);
if(algorithm!=spf&&algorithm!=rr)
cout<<"input again\n";
else break;
}
cout<<"\nnow we have "<<n<<" processes,initial their PCB at first:\n\n";
Listp=Listhead->next;
for(i=0;i<=n-1;i++)
{
cout<<"basic information of PCB about No."<<i<<" process:\n\n";
Listp->id=i;
Listp->cputime=rand()%MAX;
cout<<"the time has been run: "<<Listp->cputime<<endl;
Listp->alltime=rand()%MAX;
cout<<"the time still need to run : "<<Listp->alltime<<endl;
Listp->startblock=rand()%MAX;
cout<<"when to block: "<<Listp->startblock<<endl;
Listp->blocktime=rand()%MAX;
cout<<"block time : "<<Listp->blocktime<<endl;
cout<<"input the state of process (run:0; ready:1; block:2):";
while(1){
if(!(cin>>num2)) {cerr<<"error";exit(0);}
if(num2!=0&&num2!=1&&num2!=2) {cout<<"the state is incorrect,input again:\n";}
else break;
}
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; // 就緒
PCBpp Block=new PCBptr[100]; // 阻塞
for( i=0;i<=99;i++) *(Block+i)=0; //
PCBpp BlockEnd=Block; // 隊列
if(algorithm==spf) ReadyEnd++;//如果是Spf算法,用直接插入排序,*Ready是哨兵,Ready+1成爲隊頭。
for(Listp=Listhead;Listp->next;Listp=Listp->next)
{//把初始化的進程放進各自隊列
switch(Listp->next->state)
{
case running:*Run=Listp->next;break;
case ready:
{
*ReadyEnd=Listp->next;ReadyEnd++;
if(algorithm==spf)
InsertSort(Ready,ReadyEnd,algorithm);
break;
}
case blocked:*BlockEnd=Listp->next;BlockEnd++;break;
}
}
cout<<"\nnow the "<<n<<" processes start to run.............\n\n";
// cin>>x;
for(time=1;Listhead->next;time++)
{//開始併發執行。
cout<<"\nafter "<<time<<" timeslice:";
if(*Run)
{//Run隊列的變化。
(*Run)->cputime++;
if((*Run)->alltime>0)
(*Run)->alltime--;
if((*Run)->startblock>0)
(*Run)->startblock--;
}
if(*Block)
{//Block隊列的變化。
for(pp=Block;pp!=BlockEnd;pp++)
if((*pp)->blocktime>0)
(*pp)->blocktime--;
}
Print(Listhead);
if(*Block)
{
pp=Block;
while(pp!=BlockEnd)
{//把已經阻塞好了的進程移到就緒隊列。
if((*pp)->blocktime==0)
{
(*pp)->state=ready;
*ReadyEnd=*pp;ReadyEnd++;
if(algorithm==spf)
InsertSort(Ready,ReadyEnd,algorithm);
for(PCBpp ss=pp;ss!=BlockEnd;ss++)
*ss=*(ss+1);
BlockEnd--;
}
else pp++;
}
}
if(*Run)
{
if((*Run)->alltime==0)
{//如果運行完了,把該進程撤銷,並拿就緒隊頭的進程來運行。
Delete(Listhead,*Run);
RdyToRun(Ready,Run,algorithm);
}
else
{//沒運行完
if((*Run)->startblock==0)
{//如果該阻塞了,則 放入阻塞隊列,運行就緒隊頭進程。
RunToBlk(Run,BlockEnd);
RdyToRun(Ready,Run,algorithm);
}
else
{//如果沒阻塞
if(algorithm==rr)
{//在rr算法下就加入就緒隊尾。
(*Run)->state=ready;
*ReadyEnd=*Run;
ReadyEnd++;
if(*Ready)
{
(*Ready)->state=running;
*Run=*Ready;
Ready++;
}
}
}
}
}
else
RdyToRun(Ready,Run,algorithm);
}
return 0;
}