/*********************************/
程序名稱:進程調度算法:先來先服務算法、時間片輪轉調度算法的實現
copyright@ pengkuny
主頁:http://www.shnenglu.com/pengkuny
完成日期:2006.12.01
參考資料:湯子瀛<<計算機操作系統>>
/********************************/
//?時間片輪轉調度算法
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using?namespace?std;
enum?STATUS?
{RUN,READY,WAIT,FINISH};
struct?PCBNode

{????????
????int??processID;??????????????//進程ID
????STATUS??status;??????????????//進程狀態
????int??priorityNum;??????????//優先數
????int??reqTime;?????????????//總的需要運行時間
????int??remainTime;??????????//剩下需要運行時間
????int??arriveTime;??????????//進入就緒隊列時間
????int??startTime;???????????//開始運行時間
????int??finishTime;??????????//結束運行時間
????int??totalTime;???????????//周轉時間
????float??weightTotalTime;??????//帶權周轉時間????
};
struct?QueueNode?

{
????int?ID;??????????//進程ID
????struct?QueueNode?*?next;???//隊列中下一個進程指針
};
struct?LinkQueue

{
????QueueNode?*head;//隊首
};
void Fcfs(LinkQueue& Q, int& totalTimeSum, int& weightTotalTimeSum,PCBNode * ProcessTable);
bool?RR_Run(LinkQueue&?Q,QueueNode*?q,?QueueNode*?p,?const?int?Round,int&?currentTime,PCBNode?*?ProcessTable);
//分配時間片給q所指進程,p為剛退出的進程
void?RoundRobin(LinkQueue&?Q,const?int?Round,?int&?totalTimeSum,?int&?weightTotalTimeSum,PCBNode?*?ProcessTable);
//時間片輪轉調度,調用RR_Run(),時間片大小設為Round
void?InitialQueue(LinkQueue&?Q,PCBNode?*?ProcessTable,const?int?processnum);
//初始化就緒隊列
void?Input(PCBNode?*?ProcessTable,?const?int?processnum);
//從input.txt文件輸入數據
int?main()

{
????LinkQueue?Q;//就緒隊列
????Q.head?=?NULL;
????const?int?processnum?=?16;//進程數
????const?int?Round?=?1;??????//時間片大小
????int?totalTimeSum?=?0;?????//周轉時間
????int????WeightTotalTimeSum?=?0;//帶權周轉時間
????PCBNode?*?ProcessTable=new?PCBNode[processnum];???//進程表
????Input(ProcessTable,?processnum);
????InitialQueue(Q,?ProcessTable,?processnum);
????RoundRobin(Q,?Round,?totalTimeSum,WeightTotalTimeSum,ProcessTable);????
????cout<<"時間片輪調度的平均周轉時間為:"<<totalTimeSum/processnum<<endl;
????cout<<"時間片輪調度的平均帶權周轉時間為:"<<WeightTotalTimeSum/processnum<<endl;
????Input(ProcessTable,?processnum);
????InitialQueue(Q,?ProcessTable,?processnum);
????Fcfs(Q,?totalTimeSum,WeightTotalTimeSum,ProcessTable);
????cout<<"先來先服務的平均周轉時間為:"<<totalTimeSum/processnum<<endl;
????cout<<"先來先服務的平均帶權周轉時間為:"<<WeightTotalTimeSum/processnum<<endl;
????delete?[]?ProcessTable;
????return?0;
}
void?RoundRobin(LinkQueue&?Q,const?int?Round,?int&?totalTimeSum,?int&?weightTotalTimeSum,PCBNode?*?ProcessTable)

{
????totalTimeSum?=?0;???//總的周轉時間
????weightTotalTimeSum?=?0;//平均周轉時間
????int?currentTime?=?0;???//當前時間
????QueueNode*?p;
????QueueNode*?q;
????QueueNode*?r;
????bool?finish?=?false;//調用RR_Run()后,該進程是否已經做完退出
????
????p?=?Q.head;
????q?=?p->next;
????while?(q?!=?NULL)//從隊首開始依次分配時間片
????
{
????????do
????????
{????????
????????????cout<<"**********************"<<endl;
????????????cout<<"在時間片"<<(currentTime+1)/Round<<"內,活動進程為:??"<<q->ID<<endl;
????????????cout<<"進程"<<q->ID<<"?現在需要的時間片為:??"<<ProcessTable[q->ID].remainTime<<endl;
????????????finish?=?RR_Run(Q,?q,?p,?Round,?currentTime,?ProcessTable);//分配時間片給q進程
????????????cout<<endl;
????????????
????????????if?(!finish)//若是進程在本時間片內做完,則跳出do…while循環
????????????
{????????????
????????????????if?(q->next?==?NULL)?
????????????????
{
????????????????????r?=?Q.head->next;
????????????????}
????????????????else
????????????????
{
????????????????????r?=?q->next;
????????????????}
????????????}
????????????else?//否則計算周轉時間和帶權周轉時間
????????????
{
????????????????totalTimeSum?+=?ProcessTable[q->ID].totalTime;
????????????????weightTotalTimeSum?+=?ProcessTable[q->ID].weightTotalTime;
????????????????delete?q;?//從隊列中刪除q進程
????????????????q?=?p;
????????????}
????????}while?(!finish?&&??(ProcessTable[r->ID].arriveTime?>?currentTime?+?Round));
????????//下一個進程很晚才來,則繼續給當前進程分配時間片
????????
????????p?=?q;
????????q?=?q->next;
????????if?(q?==?NULL?&&?Q.head->next!=NULL)
????????
{
????????????p?=?Q.head;
????????????q?=?p->next;
????????}?
????}?
????delete?Q.head;
????Q.head?=?NULL;
}
bool?RR_Run(LinkQueue&?Q,QueueNode*?q,?QueueNode*?p,?const?int?Round,int&?currentTime,PCBNode?*?ProcessTable)

{
????if?(ProcessTable[q->ID].remainTime?<=?Round)//在此時間片內能夠做完,之后退出進程調度
????
{
????????ProcessTable[q->ID].finishTime?=?currentTime?+?ProcessTable[q->ID].remainTime;
????????ProcessTable[q->ID].totalTime?+=?ProcessTable[q->ID].remainTime;
????????ProcessTable[q->ID].weightTotalTime?=?ProcessTable[q->ID].totalTime/ProcessTable[q->ID].reqTime;????????
????????currentTime?=?ProcessTable[q->ID].finishTime;
????????
????????p->next?=?q->next;
????????cout<<endl;
????????cout<<"進程"<<q->ID<<"完成!"<<endl;
????????return?true;
????}
????else//此時間片內做不完
????
{
????????ProcessTable[q->ID].remainTime?=?ProcessTable[q->ID].remainTime?-?Round;
????????ProcessTable[q->ID].totalTime?+=?Round;
????????currentTime?+=?Round;
????????
????????return?false;
????}
}

void?Fcfs(LinkQueue&?Q,?int&?totalTimeSum,?int&?weightTotalTimeSum,PCBNode?*?ProcessTable)

{
????totalTimeSum?=?0;
????weightTotalTimeSum?=?0;//平均周轉時間
????QueueNode*?p;
????QueueNode*?q;
????
????p?=?Q.head->next;
????if?(p?!=NULL?)?
????
{
????????ProcessTable[p->ID].startTime?=?ProcessTable[p->ID].arriveTime;
????????ProcessTable[p->ID].finishTime?=?ProcessTable[p->ID].arriveTime?+?ProcessTable[p->ID].reqTime;
????}
????
????for(q=p->next;?q!=NULL;?q=q->next)
????
{
????????
????????if?(ProcessTable[q->ID].arriveTime?<?ProcessTable[p->ID].finishTime)
????????
{
????????????ProcessTable[q->ID].startTime?=?ProcessTable[p->ID].finishTime;
????????????ProcessTable[q->ID].finishTime?=?ProcessTable[p->ID].finishTime?+?ProcessTable[q->ID].reqTime;
????????}
????????else//下個進程到達時間較晚
????????
{
????????????ProcessTable[q->ID].startTime?=?ProcessTable[q->ID].arriveTime;
????????????ProcessTable[q->ID].finishTime?=?ProcessTable[q->ID].arriveTime?+?ProcessTable[q->ID].reqTime;
????????}
????????p?=?q;
????}
????
????for(q=Q.head->next;?q!=NULL;?q=q->next)
????
{
????????ProcessTable[q->ID].totalTime?=?ProcessTable[q->ID].finishTime?-?ProcessTable[q->ID].arriveTime;
????????ProcessTable[q->ID].weightTotalTime?=?ProcessTable[q->ID].totalTime/ProcessTable[q->ID].reqTime;????????
????????totalTimeSum?+=?ProcessTable[q->ID].totalTime;
????????weightTotalTimeSum?+=?ProcessTable[q->ID].weightTotalTime;
????}????
????
????int?t?=?0;
????for(q=Q.head->next;?q!=NULL;?q=q->next)
????
{
????????cout<<"*********************"<<endl;
????????while?(?t<ProcessTable[q->ID].finishTime?)
????????
{
????????????cout<<"時刻"<<t<<":??進程"<<q->ID<<"活動"<<endl;
????????????t++;
????????}
????????if?(q->next?!=?NULL)
????????
{????
????????????cout<<"時刻"<<t<<":??進程"<<q->ID<<"結束活動,開始下一個進程."<<endl;
????????????cout<<"進程"<<q->ID<<"的周轉時間為:?"<<ProcessTable[q->ID].totalTime<<endl;
????????????cout<<"進程"<<q->ID<<"的帶權周轉時間為:?"<<ProcessTable[q->ID].weightTotalTime<<endl<<endl;
????????}
????????else
????????
{
????????????cout<<"時刻"<<t<<":??進程"<<q->ID<<"結束活動."<<endl<<endl;
????????????cout<<"進程"<<q->ID<<"的周轉時間為:?"<<ProcessTable[q->ID].totalTime<<endl;
????????????cout<<"進程"<<q->ID<<"的帶權周轉時間為:?"<<ProcessTable[q->ID].weightTotalTime<<endl<<endl;????????????
????????}
????}
????cout<<"所有進程結束活動."<<endl<<endl;
????p?=?Q.head;
????for(q=p->next;?q!=NULL;?q=q->next)
????
{
????????delete?p;
????????p?=?q;
????}
}

void?InitialQueue(LinkQueue&?Q,?PCBNode?*?ProcessTable,const?int?processnum)

{
????//初始化
????
????for?(int?i=0;i<processnum;i++)
????
{
????????ProcessTable[i].processID=i;
????????ProcessTable[i].reqTime=ProcessTable[i].remainTime;
????????ProcessTable[i].finishTime=0;
????????ProcessTable[i].startTime=0;????
????????ProcessTable[i].status=WAIT;
????????ProcessTable[i].totalTime=0;
????????ProcessTable[i].weightTotalTime=0;????????
????}
????
????Q.head?=?new?QueueNode;
????Q.head->next?=?NULL;
????QueueNode?*?p;
????QueueNode?*?q;
????for?(i=0;i<processnum;i++)
????
{????
????????p?=?new?QueueNode;
????????p->ID?=?i;
????????p->next?=?NULL;
????????if?(i?==?0)
????????
{
????????????Q.head->next?=?p;????????????
????????}
????????else
????????????q->next?=?p;
????????
????????q?=?p;
????}
}

void?Input(PCBNode?*?ProcessTable,?const?int?processnum)

{
????FILE?*fp;????????//讀入線程的相關內容
????if((fp=fopen("input.txt","r"))==NULL)
????
{
????????cout<<"can?not?open?file!"<<endl;
????????exit(0);
????}????????
????for(int?i=0;i<processnum;i++)
????
{
????????fscanf(fp,"%d?%d?%d",&ProcessTable[i].arriveTime,&ProcessTable[i].remainTime,&ProcessTable[i].priorityNum);
????}
????fclose(fp);
}


建議輸入數據:input.txt
0????4????? 0
1? ? 35???? 1
2????10???? 2
3? ? 5????? 3
6?? ?9????? 4
7?? ?21???? 5
9??? 35???? 6
11 ?23???? 7
12? 42???? 8 ?
13?? 1????? 9
14?? 7???? 10
20? ?5???? 11
23? ?3???? 12
24? ?22??? 13
25?? 31??? 14
26?? 1???? 15
