操作系统–时间片轮转调度算法(RR算法)
实验内容:
模拟实现时间片轮转调度算法,具体如下:
设置进程体:进程名,进程的到达时间,服务时间,,进程状态(W——等待,R——运行,F——完成),进程间的链接指针
进程初始化:由用户输入进程名、服务时间进行初始化,同时,初始化进程的状态为W。
显示函数:在进程调度前、调度中和调度后进行显示。
排序函数:对就绪状态的进程按照进入就绪队列的时间排序,新到达的进行应优先于刚刚执行过的进程进入就绪队列的队尾。注意考虑到达时间
调度函数:每次从就绪队列队首调度优一个进程执行,状态变化。并在执行一个时间片后化,服务时间变化,状态变化。当服务时间为0时,状态变为F。
删除函数:撤销状态为F的进行。
只写了时间片为1的情况大致的思想有点像模拟一个队列。
代码:
#include <bits/stdc++.h>
using namespace std;
const int MAX = 109;
#define W "waitting"
#define R "running"
#define F "finish"
class WORK
{
public:
string work_name; // 作业名
int serve_time; // 剩余服务时间
int r_serve_time; // 服务时间
int arrive_time; // 到达时间
string work_state; // 作业状态
int end_time; // 结束时间
int turnover_time; // 周转时间
WORK & operator=(const WORK &wo) // 重载赋值运算符
{
work_name = wo.work_name;
serve_time = wo.serve_time;
r_serve_time = wo.r_serve_time;
arrive_time = wo.arrive_time;
work_state = wo.work_state;
end_time = wo.end_time;
turnover_time = wo.turnover_time;
return *this;
}
};
WORK work[MAX]; // 作业
int n; // 作业数量
int q; // 时间片
bool cmp_SJF(WORK x, WORK y) // 排序函数
{
if(x.serve_time != y.serve_time) // 服务时间不同时短作业优先
return x.serve_time < y.serve_time;
else // 服务时间相同时先来先服务
return x.arrive_time < y.arrive_time;
}
bool cmp_arr_time(WORK x, WORK y) // 按到达时间从小到大排序
{
return x.arrive_time < y.arrive_time;
}
int count_work(int t) // 计算某一时间有多少个作业进入
{
int cnt = 0;
for(int i = 1; i <= n; i++)
{
if(work[i].arrive_time <= t)
cnt++;
}
return cnt;
}
void insert_work(int num) // 插入新作业
{
if(num > 2)
{
int t_num = num - 1;
WORK t_work[MAX];
t_work[1] = work[t_num];
t_work[2] = work[num];
for(int i = 1; i <= num - 2; i++)
{
t_work[i + 2] = work[i];
}
for(int i = 1; i <= num; i++)
work[i] = t_work[i];
}
}
void cir_work(int num) // 循环
{
WORK t_work;
t_work = work[num];
for(int i = num - 1; i >= 1; i --)
work[i + 1] = work[i];
work[1] = t_work;
}
void update_work(int num, int c_time, bool is_new) // 更新当前要调度的作业
{
if(is_new) // 新来了作业, 插入新来的作业
insert_work(num);
else // 没有新作业进入, 对原作业循环
cir_work(num);
int t = 0;
bool is_ok = false;
int cnt = 0;
while(!is_ok)
{
if(work[num].serve_time > 0) // 作业还没结束
{
work[num].serve_time --;
work[num].work_state = R;
t = num;
is_ok = true;
break;
}
if(work[num].serve_time <= 0) // 作业已经结束
{
work[num].serve_time = 0;
work[num].work_state = F;
cir_work(num);
cnt++;
}
if(cnt == n)
break;
}
for(int i = 1; i <= n; i++) // 更新状态
{
if(i != t)
{
if(work[i].work_state != F)
work[i].work_state = W;
if(work[i].serve_time <= 0)
work[i].work_state = F;
}
if(work[i].work_state == F && work[i].end_time == -1)
work[i].end_time = c_time;
}
}
bool judge_over() // 判断作业是否全部完成
{
for(int i = 1; i <= n; i++)
if(work[i].work_state != F)
return false;
return true;
}
int main()
{
cout << "请输入要调度的作业:" << endl;
cout << "要调度的作业的数量:" ;
cin >> n;
for(int i = 1; i <= n; i++)
{
cout << "作业名: " << endl;
cin >> work[i].work_name;
cout << "作业服务时间: " << endl;
cin >> work[i].serve_time;
cout << "作业到达时间: " << endl;
cin >> work[i].arrive_time;
work[i].work_state = W;
work[i].end_time = -1;
work[i].r_serve_time = work[i].serve_time;
}
sort(work + 1, work + 1 + n, cmp_arr_time); // 先按到达时间排序
cout << "作业初始状态:" << endl;
cout << " 作业名 " << " 到达时间 " << " 服务时间 " << " 当前状态 " << endl;
for(int i = 1; i <= n; i++)
{
cout << setw(8) << work[i].work_name << setw(16) << work[i].arrive_time << setw(13)
<< work[i].serve_time<< setw(21) << work[i].work_state << endl;
}
cout << endl;
int arrive_num = 0; // 已到达的作业数量
int current_time = 0; // 当前时间
cout << "作业调度情况如下:" << endl;
bool is_over = false;
int current_work_num = 0;
while(!is_over)
{
cout << " 时刻 " << " 作业名 " << " 到达时间 " << " 剩余服务时间 " << " 当前状态 " << endl;
arrive_num = count_work(current_time);
update_work(arrive_num, current_time, current_work_num < arrive_num);
current_work_num = arrive_num;
int cou = 0;
for(int i = 1; i <= arrive_num; i++)
{
if(work[i].work_state != F)
{
cou ++;
cout << setw(6) << current_time << setw(13) << work[i].work_name << setw(15) << work[i].arrive_time << setw(15)
<< work[i].serve_time << setw(24) << work[i].work_state << endl;
}
}
if(cou == 0)
cout << setw(6) << current_time << setw(30) << "所有作业均执行完毕!" << endl << endl;
current_time ++;
is_over = judge_over();
if(current_time == 14)
break;
cout << endl;
}
cout << "各作业的周转时间和带权周转时间如下:" << endl;
cout << " 作业名 " << " 周转时间 " << " 带权周转时间 " << endl;
for(int i = 1; i <= n; i++)
{
work[i].turnover_time = work[i].end_time - work[i].arrive_time; // 周转时间
double wight_time = 1.0 * work[i].turnover_time / work[i].r_serve_time; // 带权周转时间
cout << setw(6) << work[i].work_name << setw(15) << work[i].turnover_time << setw(18);
cout.precision(4);
cout << wight_time << endl;
}
return 0;
}
运行结果:
根据提示输入数据如图:
显示各个作业的初始状态:
各个时刻作业的调度情况如下:
各个作业的周转时间和带权周转时间如下:
根据输入样例手动画出时间片轮转算法的调度时间图如下:
与运行结果相比,发现运行正确(我只测试了这一个样例,是我们慕课作业上面的),如有问题,欢迎指正~~