目 录
一、实验目的及要求
1.实验目的
通过程序模拟进程的时间片轮转调度算法RR和多级反馈队列调度算法MRLA的运行过程,并将相关的数据信息进行屏幕显示,掌握这些算法调度进程的顺序和依据,并将相关的运行结果进行打印输出。
2.实验要求
1)进程个数3个及以上(动态输入),每个进程至少要有进程代号、到达时间、运行时间、开始时间、结束时间、周转时间、带权周转时间、平均周转时间、平均带权周转时间以及进程的切换次数等相关信息。
2)在窗口输出进程的开始和结束运行信息模拟进程的运行过程,并且在开始的时候显示进程调度的过程。
3)在设计的程序中有相关的打印函数进行相关信息的打印输出,可以正常显示和打印进程调度的过程、进程代号、到达时间、运行时间、开始时间、结束时间、周转时间、带权周转时间等输出信息,给出各进程的平均周转时间和平均带权周转时间以及进程的切换次数。
二、实验环境(工具、配置等)
1.硬件要求:笔记本电脑一台。
2.软件要求:Windows10操作系统,通过Dev-cpp编译环境使用C++编程语言。
三、实验内容(实验方案、实验步骤、设计思路等)
1.实验方案
根据老师上课所讲以及课本知识的结合,通过Dev-cpp编译环境使用C++编程语言编写时间片轮转调度算法RR和多级反馈队列调度算法MRLA,并通过调用相关的打印函数对相关的数据进行打印输出,看是否与预期结果一样。
2.实验步骤
在书上以及网上查找相关的算法并进行理解式学习,将自己理解的算法思路上机进行运行测试。对运行过程中出现的错误进行分析和总结,对遇到的问题进行解决。
3.设计思路
打开Dev-cpp编译环境进行相关算法的编写及运行。
(1)导入运行过程中所需要的相关的头文件。
(2)创建进程调度算法的结构体,在结构体中定义相关的变量。
(3)编写时间片轮转调度算法RR和多级反馈队列调度算法MRLA进行测试。
(4)编写打印函数将相关的数据信息进行打印输出(进程调度的过程、进程代号、到达时间、运行时间、开始时间、结束时间、周转时间、带权周转时间、进程的平均周转时间、平均带权周转时间以及进程的切换次数等)。
(5)在主函数中调用相关的函数进行程序的正常运行。
(6)对程序中遇到的相关问题进行分析和总结。
(7)完成计算机操作系统实验报告的书写及提交。
四、实验结果与分析
1.打开Dev-cpp编译环境,对相关的测试数据进行键盘输入,如图4-1:
图4-1 窗口数据的输入窗口
2.使用C++编译语言编写时间片轮转调度算法RR并将运行结果中的相关数据进行打印输出,如图4-2:
图4-2 时间片轮转调度算法
3.使用C++编译语言编写多级反馈队列调度算法MRLA并将运行结果中的相关数据进行打印输出,如图4-3:
图4-3 多级反馈队列调度算法
1、实验分析
1)编译错误:“error C2057: expected constant expression”
解决方法:定义数组时数组长度为变量,将常量改为变量即可。
2)编译错误:“error C2078: too many initializers”
解决方法:数组初始化时初始值的个数大于数组长度,将数组长度扩大即可。
3)编译错误:”error C2086: 'xxx' : redefinition“
解决方法:变量名、数组名重名,将变量名或数组名中的一个进行修改即可。
4)编译错误:“error C2100: illegal indirection”
解决方法:对非指针变量使用“*”运算,将其变量修改为指针即可。
5)出现的问题:内存虽然分配成功,但是还没有初始化就进行了使用。
解决方法:在创建后数组之后,要进行赋初值,即使是零也不能省略。
2、心得体会
1)定义指针之后必须赋值,然后才可以引用。
2)任何类型的指针都可以赋值给void类型的指针变量。
3)避免数字或指针的下标越界,特别要当心发生“多1”或者“少1”操作。
4)在进行时间片轮转算法的时候要正确的定义相关的结构体,尽可能将需要的相关变量在结构体中定义好,这样在进行输入信息的时候可以避免变量的错乱。
5)多级反馈队列调度算法中的一部分内容可以与时间片轮转调度算法中的一部分重复利用,通过定义一个函数实现多个方法的调用,为编写带来遍历。
五、附流程图及源代码
1.程序运行流程图如图5-1所示:
图5-1 程序运行流程图
2.源代码:
#include<iostream>
using namespace std;
//创建进程的结构体
typedef struct Process{
int process_name;//进程代号
int process_arrive_time;//进程到达时间
int process_start_time;//进程开始时间
int process_run_time;//进程运行时间
int process_end_time;//进程结束时间
int process_run_flag;//进程的调度标识
int process_start_flag;//进程的第一次调度标识
};
//定义全局变量
int flag = 0;//判断标识
int process_count;//进程数量
int time_count;//时间片长度
int T = 0;//进程切换次数
//初始化进程结构体
void Init_process_list(Process process_list[]){
cout<<"------------开始数据填写------------"<<endl;
for(int i=0;i<process_count;i++){
cout<<"进程"<<i + 1<<"的代号为:";
cin>>process_list[i].process_name;
cout<<"进程"<<i + 1<<"的到达时间为:";
cin>>process_list[i].process_arrive_time;
cout<<"进程"<<i + 1<<"的运行时间为:";
cin>>process_list[i].process_run_time;
process_list[i].process_start_time = 0;
process_list[i].process_end_time = 0;
process_list[i].process_run_flag = 0;
process_list[i].process_start_flag = 0;
}
cout<<"------------数据填写完成------------"<<endl;
cout<<endl;
}
//进程调用RR结果打印函数
void Print_RR_information(Process process_list[]){
//定义局部变量
int turn_time = 0;//周转时间
int sum_turn_time = 0;//总周转时间
double average_turn_time = 0;//平均周转时间
int power_turntime = 0;//带权周转时间
int sum_power_turntime = 0;//总带权周转时间
double average_power_turntime = 0;//平均带权周转时间
cout<<"进程代号 到达时间 运行时间 开始时间 结束时间 周转时间 带权周转时间"<<endl;
for(int i=0;i<process_count;i++){
turn_time = process_list[i].process_end_time - process_list[i].process_arrive_time;
sum_turn_time += turn_time;
power_turntime = turn_time / process_list[i].process_run_time;
sum_power_turntime += power_turntime;
cout<<" "<<process_list[i].process_name<<" "<<process_list[i].process_arrive_time<<" "<<process_list[i].process_run_time<<" "<<process_list[i].process_start_time<<" "<<process_list[i].process_end_time<<" "<<turn_time<<" "<<power_turntime<<endl;
}
average_turn_time = sum_turn_time / process_count;
average_power_turntime = sum_power_turntime / process_count;
cout<<"平均周转时间为:"<<average_turn_time<<endl;
cout<<"平均带权周转时间为:"<<average_power_turntime<<endl;
cout<<"进程的切换次数为:"<<T - 1<<endl;
T = 0;//恢复默认值
cout<<"------------进程调度RR算法信息打印结束------------"<<endl;
}
//判断进程是否全部执行完毕
int Judgment(int flag, Process process_list[]){
//是否全部执行完毕的标识
int all_flag = 0;
for(int i=0;i<process_count;i++){
if(process_list[i].process_run_flag == 0){
all_flag = 1;
flag++;
if(flag >= 2){
time_count = 2 * time_count;
}
return all_flag;
break;
}
else{
all_flag = 0;
}
}
return all_flag;
}
//进程调用MRLA结果打印函数
void Print_MRLA_information(Process process_list[]){
//定义局部变量
int turn_time = 0;//周转时间
int sum_turn_time = 0;//总周转时间
double average_turn_time = 0;//平均周转时间
int power_turntime = 0;//带权周转时间
int sum_power_turntime = 0;//总带权周转时间
double average_power_turntime = 0;//平均带权周转时间
cout<<"进程代号 到达时间 运行时间 开始时间 结束时间 周转时间 带权周转时间"<<endl;
for(int i=0;i<process_count;i++){
turn_time = process_list[i].process_end_time - process_list[i].process_arrive_time;
sum_turn_time += turn_time;
power_turntime = turn_time / process_list[i].process_run_time;
sum_power_turntime += power_turntime;
cout<<" "<<process_list[i].process_name<<" "<<process_list[i].process_arrive_time<<" "<<process_list[i].process_run_time<<" "<<process_list[i].process_start_time<<" "<<process_list[i].process_end_time<<" "<<turn_time<<" "<<power_turntime<<endl;
}
average_turn_time = sum_turn_time / process_count;
average_power_turntime = sum_power_turntime / process_count;
cout<<"平均周转时间为:"<<average_turn_time<<endl;
cout<<"平均带权周转时间为:"<<average_power_turntime<<endl;
cout<<"进程的切换次数为:"<<T - 1<<endl;
T = 0;//恢复默认值
cout<<"------------进程调度MALA算法信息打印结束------------"<<endl;
}
//进程的运行过程
void Process_time(int flag, Process process_list[]){
//定义记录时间片已用长度的变量
int length = 0;
//定义相关变量
int i, j=0, k=0;
//实现信息备份
Process process_list_copy[process_count];
//备份信息初始化
for(i=0;i<process_count;i++){
process_list_copy[j++] = process_list[i];
}
//长度为第一个进程到达的时间
length = process_list[0].process_arrive_time;
//结果为0表示执行完毕,结果为1表示继续执行
while(Judgment(flag,process_list)){
for(i = 0;i<process_count;i++){
//更新length的记录
if(process_list[i].process_arrive_time > length){
length = process_list[i].process_arrive_time;
}
//第i个进程还未结束
if(process_list[i].process_run_flag == 0){
//进程第一次执行
if(process_list[i].process_start_flag == 0){
process_list[i].process_start_time = length;
process_list[i].process_start_flag = 1;
}
//未执行的时间片长度
if(process_list[i].process_run_time / time_count > 1){
//剩余运行时间
process_list[i].process_run_time = process_list[i].process_run_time - time_count;
//已用的时间片长度
length = length + time_count;
T++;
}
else if(process_list[i].process_run_time - time_count == 0){
length = length + time_count;
process_list[i].process_end_time = length;
//进程已经执行完毕
process_list[i].process_run_flag = 1;
process_list[i].process_run_time = process_list_copy[i].process_run_time;
T++;
}
//剩余时间片长度
else{
length = length + process_list[i].process_run_time;
process_list[i].process_end_time = length;
//该进程已经运行完毕
process_list[i].process_run_flag = 1;
process_list[i].process_run_time = process_list_copy[i].process_run_time;
T++;
}
}
}
}
}
//时间片轮转调度算法RR
void RR(Process process_list[]){
flag = -1;
Process_time(flag, process_list);
Print_RR_information(process_list);
}
//多级反馈队列调度算法MRLA
void MRLA(Process process_list[]){
flag = 0;
Process_time(flag, process_list);
Print_MRLA_information(process_list);
}
int main(){
//定义选择方法的变量
int method = 1;
//初始化进程数量
cout<<"请输入进程的数量为:";
cin>>process_count;
cout<<"请输入时间片长度为:";
cin>>time_count;
cout<<endl;
//定义进程结构体数组
Process process_list[process_count];
//初始化进程结构体数组
Init_process_list(process_list);
while(method){
cout<<"可供选择的进程调度算法如下:"<<endl;
cout<<"1-(时间片轮转调度算法RR), 2-(多级反馈队列调度算法MRLA), 00-退出程序"<<endl;
cout<<"您的选择为:";
cin>>method;
cout<<endl;
switch(method){
case 1:
cout<<"------------时间片轮转调度算法RR------------"<<endl;
RR(process_list);
cout<<endl;
break;
case 2:
cout<<"------------多级反馈队列调度算法MRLA------------"<<endl;
MRLA(process_list);
cout<<endl;
break;
default:
cout<<"输入错误,请重新输入!"<<endl;
cout<<endl;
break;
}
}
return 0;
}