本次记录高响应比调度算法的C++实现。高响应比调度算法,简单的来说就是对每个进程对计算一个响应比,根据响应比的大小来判断要运行的进程。其实现思路如下:
具体步骤为:
- 首先定义进程控制块PCB类:
class PCB
{
public:
int ID; //进程ID
int runtime; //进程已运行时间
int lasttime; //进程所需的剩余运行时间
int alltime; //进程的总运行时间
int waittime = 1; //进程等待时间
float response; //进程响应比
State state; //进程所处状态
};
- 进程初始化
实例化进程对象,并且进行初始化。其中,进程的响应比通过以下公式定义:
响应比response = 等待时间waittime / 进程总运行时间alltime + 1
vector<PCB>process;
for (int i = 0;i < 5;i++)
{
PCB pcb;
process.push_back(pcb);
}
process[0].ID = 0;
process[0].runtime = 0;
process[0].lasttime = 30;
process[0].alltime = process[0].runtime + process[0].lasttime;
process[0].response = float(process[0].waittime) / float(process[0].alltime) + 1.0;
process[0].state = wait;
process[1].ID = 1;
process[1].runtime = 0;
process[1].lasttime = 20;
process[1].alltime = process[1].runtime + process[1].lasttime;
process[1].response = float(process[1].waittime) / float(process[1].alltime) + 1.0;
process[1].state = wait;
process[2].ID = 2;
process[2].runtime = 0;
process[2].lasttime = 10;
process[2].alltime = process[2].runtime + process[2].lasttime;
process[2].response = float(process[2].waittime) / float(process[2].alltime) + 1.0;
process[2].state = wait;
process[3].ID = 3;
process[3].runtime = 0;
process[3].lasttime = 40;
process[3].alltime = process[3].runtime + process[3].lasttime;
process[3].response = float(process[3].waittime) / float(process[3].alltime) + 1.0;
process[3].state = wait;
process[4].ID = 4;
process[4].runtime = 0;
process[4].lasttime = 50;
process[4].alltime = process[4].runtime + process[4].lasttime;
process[4].response = float(process[4].waittime) / float(process[4].alltime) + 1.0;
process[4].state = wait;
- 运行调度算法
获取5个进程的响应比,寻找其中处于就绪状态且响应比最高的进程,并运行该进程。将该运行进程的运行时间加1、剩余运行时间减1,其他就绪进程的等待时间加1,再重新计算各个进程的响应比。
直到某个进程的剩余运行时间为0,则表示该进程已经运行结束,则将进程状态置为finish,否则在当前时间片结束后将该进程状态置为wait。
打印当前调度的进程信息,循环进行调度算法,直到所有进程的状态都为finish则退出循环,高响应比调度算法结束。
int timeslice = 0; //运行消耗的时间片
int flag = 0; //已经运行完毕的进程数
while (process[0].lasttime || process[1].lasttime || process[2].lasttime || process[3].lasttime || process[4].lasttime)
{
float responses[5];
for (int i = 0;i < 5;i++)
{
//获取5个进程的响应比,如果某个进程已运行结束则将响应比缓冲区中对应值置为0
float process_responses[] = { process[0].response,process[1].response,process[2].response,process[3].response,process[4].response };
for (int k = 0;k < 5;k++)
{
if (process[k].state == finish)
{
process_responses[k] = 0;
}
}
//如果某进程处于就绪状态,且其响应比是所有就绪进程中最高的,则运行该进程
if ((process[i].state == wait) && (process[i].response == *max_element(process_responses, process_responses + 5)))
{
process[i].state = run;
cout << "进程" << process[i].ID << "开始运行" << endl;
//将该进程的运行时间加1、剩余运行时间减1
process[i].runtime += 1;
process[i].lasttime -= 1;
//将其他就绪进程的等待时间加1,且重新计算响应比
for (int j = 0;j < 5;j++)
{
if (i == j || process[j].state==finish)
{
continue;
}
process[j].waittime += 1;
process[j].response = float(process[j].waittime) / float(process[j].alltime) + 1.0;
}
//如果该进程的剩余运行时间为0,则将该进程状态置为finish,同时flag+1
if (0 == process[i].lasttime)
{
process[i].state = finish;
flag++;
}
//如果该进程的剩余运行时间不为0,则将该进程状态置为wait
else
{
process[i].state = wait;
}
//打印进程信息
cout << "进程" << process[i].ID << "结束运行" << endl;
printMessage();
}
}
timeslice++;
if (5 == flag)
{
cout << "所有进程运行结束," << "消耗运行时间片:" << timeslice << endl;
break;
}
}
其中使用printMessage()
来进行进程信息打印工作,具体代码如下:
void printMessage()
{
cout << "等待队列:";
for (int j = 0; j < 5; j++) {
if (process[j].state == wait)
{
cout << " " << process[j].ID;
}
}
cout << endl;
cout << "运行完毕队列:";
for (int j = 0; j < 5; j++) {
if (process[j].state == finish)
{
cout << " " << process[j].ID;
}
}
cout << endl;
cout << "ID\talltime\truntime\tlasttime\tresponse\twaittime\tstate" << endl;
for (int j = 0; j < 5; j++) {
cout << process[j].ID << '\t' << process[j].alltime << '\t' << process[j].runtime << '\t' << process[j].lasttime << '\t' << '\t' << process[j].response << '\t' << '\t' << process[j].waittime << '\t' << '\t' << process[j].state << endl;
}
cout << "--------------------------------------------------------" << endl;
}
实现效果如下:
至此,实现了高响应比调度算法的C++实现。
高响应比调度算法既考虑作业的执行时间也考虑作业的等待时间,综合了先来先服务和最短作业优先两种算法的特点,其优势在于短作业与先后次序的兼顾,且不会使长作业长期得不到服务,但是其缺点也很明显,由于每次进行调度都需要计算每个作业的响应比导致了系统开销的增加。