实验题目
随机给出一个进程调度实例,如:
进程 到达时间 服务时间
A 0 3
B 2 6
C 4 4
D 6 5
E 8 2
模拟进程调度,给出按照算法先来先服务FCFS、轮转RR(q=1)、最短进程优先SPN、最短剩余时间SRT、最高响应比优先HRRN进行调度各进程的完成时间、周转时间、响应比的值。
代码
#include <iostream>
#include <queue>
using namespace std;
#define MAX_TASK 128 //最多线程数
struct A
{
char name; //进程名称
int arrive; //到达时间
int time; //服务时间
int start; //开始时间
int end; //结束时间
float rate; //响应比
bool activated; //是否到达
int rest; //剩余时间
};
/*
结束时间=开始时间+服务/执行时间(无抢断)
周转周期=结束时间-到达时间
响应比的值(带权周转时间)=周转时间/服务时间
=(结束时间-到达时间)/服务时间
*/
void FCFS(A a[], int n)
{
//先来先服务是最简单的策略,也成为先进先出FIFO。首先它是一个非抢占的。
//如字面的意思,它根据进程到达时间决定先运行哪一个进程。
for (int i = 0; i < n; i++)
{
if (i > 0 && a[i].arrive < a[i - 1].end)
{
a[i].start = a[i - 1].end;
a[i].end = a[i].start + a[i].time;
}
else
{
a[i].start = a[i].arrive;
a[i].end = a[i].start + a[i].time;
}
a[i].rate = (float)(a[i].end - a[i].arrive) / a[i].time; //求相应比
cout << a[i].name << " " << a[i].end << " " << a[i].end - a[i].arrive << " " << a[i].rate << endl;
//进程名 进程结束时间 周转周期 响应比
}
}
void RR(A a[], int n)
{
//轮转也称时间片技术(time slicing,SL),对于轮转法,最重要的是时间片的长度
//转算法以一个周期(q)产生中断,当中断发生时,当前运行的程序置于就绪队列(队尾)
//中,然后基于FCFS选择下一个就绪作业运行
queue<A> q;//轮转队列
A temp;
A b[MAX_TASK];
for (int i = 0; i < n; i++)
{
b[i] = a[i];
}
int time_now = 0;
q.push(a[0]);
while (!q.empty())
{
time_now++;
temp = q.front();
q.pop();//删除队首元素
temp.time--;
for (int i = 1; i < n; i++)
{
if (a[i].arrive == time_now)//就绪进程进入队尾
{
q.push(a[i]);
}
}
if (temp.time != 0)//当前进程未运行完
{
q.push(temp);//把当前运行进程插入队尾
}
else
{
temp.end = time_now;
for (int i = 0; i < n; i++)
{
if (temp.name == a[i].name)
{
a[i] = temp;
a[i].rate = (float)(a[i].end - a[i].arrive) / b[i].time;
}
}
}
}
for (int i = 0; i < n; i++)
{
cout << a[i].name << " " << a[i].end << " " << a[i].end - a[i].arrive << " " << a[i].rate << endl;
}
}
void SPN(A a[], int n) //最短进程优先SPN
{
//最短作业优先(Short Job First,SJF)。
//它也是一个非抢占的。是根据服务的时间经行选择。
//要注意下到达时间的顺序,有多个进程等待时选择服务时间最少的进程
int now = 0; //正在运行进程标志
int min = 100; //最短进程时间
int time_now = a[0].arrive; //标志当前时间
//假设输入默认按到达时间升序或默认a[0]最早到达
for (int i = 0; i < n; i++)
{
for (int k = 0; k < n; k++) //检查所有进程,是否已到达
{
if (a[k].arrive <= time_now && a[k].time != 0) //获取到达的进程
{
a[k].activated = true;
}
}
for (int l = 0; l < n; l++) //循环遍历找到当前既到达又最短的进程 a[now]
{
if (a[l].time < min && a[l].activated == true)
{
min = a[l].time;
now = l;
}
}
a[now].start = time_now;
a[now].end = a[now].start + a[now].time; //当前进程结束时间
time_now = a[now].end; //下一个进程开始时间
a[now].rate = (float)(a[now].end - a[now].arrive) / a[now].time;
a[now].activated = false;
a[now].time = 0; //去除当前进程
min = 100;
}
for (int i = 0; i < n; i++) //输出
{
cout << a[i].name << " " << a[i].end << " " << a[i].end - a[i].arrive << " " << a[i].rate << endl;
}
}
void SRT(A a[], int n) //最短剩余时间优先SRT
{
//SRT是针对SPN增加了抢占机制的版本,
//就好比某个进程运行时间非常长,在这期间其他所有的进程都在等待,
//如果将其中断,先处理所需时间少的,运行效率会有显著提升。
int now = 0; //正在运行进程标志
int min = 100; //最短进程时间
int time_now = a[0].arrive; //标志当前时间
//假设输入默认按到达时间升序
for (int i = 0; i < n; i++)
a[i].rest = a[i].time;
for (int i = 0; i < n; i++)
{
for (int j = 0;; j++)
{
for (int k = 0; k < n; k++) //检查所有进程,是否已到达
{
if (a[k].arrive <= time_now && a[k].time != 0) //获取到达的进程
{
a[k].activated = true;
}
}
for (int l = 0; l < n; l++)
{
if (a[l].rest < min && a[l].activated == true)//找到当前既到达剩余又最短的进程 a[now]
{
min = a[l].rest;
now = l;
}
}
a[now].start = time_now;
int m = 0;
for (m = 0; m < n; m++)
{
if (m != now && a[m].arrive < time_now + a[now].rest && a[m].time != 0 && a[m].activated == false)
{//找到当前到达的进程
time_now = a[m].arrive;
a[now].rest = a[now].start + a[now].rest - time_now;
if (a[m].rest < a[now].rest)//抢断
{
now = m;
break;
}
}
}
if (m == n)//当前进程未被抢断,运行完成
{
a[now].end = time_now + a[now].rest;
time_now = a[now].end; //下一个进程开始时间
a[now].rate = (float)(a[now].end - a[now].arrive) / a[now].time;
a[now].activated = false;
a[now].time = 0; //去除当前进程
break;
}
}
min = 100;
}
for (int i = 0; i < n; i++) //输出
{
cout << a[i].name << " " << a[i].end << " " << a[i].end - a[i].arrive << " " << a[i].rate << endl;
}
}
void HRRN(A a[], int n) //高响应比优先HRRN
{
//高响应比优先调度算法主要用于作业调度,
//该算法是对FCFS调度算法和SJF调度算法的一种综合平衡,
//同时考虑每个作业的等待时间和估计的运行时间。在每次进行作业调度时,
//先计算后备作业队列中每个作业的响应比,从中选出响应比最高的作业投入运行
//A 3 3 1
//B 9 7 1.16667
//C 13 9 2.25
//D 20 14 2.8
//E 15 7 3.5
int now = 0; //正在运行进程标志
int min = 1; //最短进程时间
int time_now = a[0].arrive; //标志当前时间
//假设输入默认按到达时间升序或默认a[0]最早到达
for (int i = 0; i < n; i++)
{
for (int k = 0; k < n; k++) //检查所有进程,是否已到达
{
if (a[k].arrive <= time_now && a[k].time != 0) //获取到达的进程
{
a[k].activated = true;
}
}
for (int l = 0; l < n; l++) //循环遍历找到当前既到达又响应比最高 a[now]
{
if (a[l].activated == true && a[l].time != 0)
{
a[l].rate = (float)(time_now + a[l].time - a[l].arrive) / a[l].time;
//计算当前响应比
if (min < a[l].rate)//找出相应比高的进程
{
min = a[l].rate;
now = l;
}
}
}
a[now].start = time_now;
a[now].end = a[now].start + a[now].time; //当前进程结束时间
time_now = a[now].end; //下一个进程开始时间
a[now].time = 0; //去除当前进程
min = 1;
}
for (int i = 0; i < n; i++) //输出
{
cout << a[i].name << " " << a[i].end << " " << a[i].end - a[i].arrive << " " << a[i].rate << endl;
}
}
int main()
{
A a[MAX_TASK];
int num;
cin >> num;
//输入
for (int i = 0; i < num; i++)
{
cin >> a[i].name;
cin >> a[i].arrive;
cin >> a[i].time;
a[i].activated = false;
a[i].rate = 1;
}
string method;
cin >> method; //获取算法名称
/*请在以下区域填入代码*/
if (method == "FCFS")
{
FCFS(a, num);
}
if (method == "RR")
{
RR(a, num);
}
if (method == "SPN")
{
SPN(a, num);
}
if (method == "SRT")
{
SRT(a, num);
}
if (method == "HRRN")
{
HRRN(a, num);
}
system("pause");
return 0;
}