《计算机操作系统》实验报告二 进程调度算法的模拟

目  录

一、实验目的及要求

1.实验目的

2.实验要求

二、实验环境(工具、配置等)

三、实验内容(实验方案、实验步骤、设计思路等)

1.实验方案

2.实验步骤

3.设计思路

四、实验结果与分析

1、实验分析

2、心得体会

五、附流程图及源代码


一、实验目的及要求

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;
}
CH341A编程器是一款广泛应用的通用编程设备,尤其在电子工程和嵌入式系统开发领域中,它被用来烧录各种类型的微控制器、存储器和其他IC芯片。这款编程器的最新版本为1.3,它的一个显著特点是增加了对25Q256等32M芯片的支持。 25Q256是一种串行EEPROM(电可擦可编程只读存储器)芯片,通常用于存储程序代码、配置数据或其他非易失性信息。32M在这里指的是存储容量,即该芯片可以存储32兆位(Mbit)的数据,换算成字节数就是4MB。这种大容量的存储器在许多嵌入式系统中都有应用,例如汽车电子、工业控制、消费电子设备等。 CH341A编程器的1.3版更新,意味着它可以与更多的芯片型号兼容,特别是针对32M容量的芯片进行了优化,提高了编程效率和稳定性。26系列芯片通常指的是Microchip公司的25系列SPI(串行外围接口)EEPROM产品线,这些芯片广泛应用于各种需要小体积、低功耗和非易失性存储的应用场景。 全功能版的CH341A编程器不仅支持25Q256,还支持其他大容量芯片,这意味着它具有广泛的兼容性,能够满足不同项目的需求。这包括但不限于微控制器、EPROM、EEPROM、闪存、逻辑门电路等多种类型芯片的编程。 使用CH341A编程器进行编程操作时,首先需要将设备通过USB连接到计算机,然后安装相应的驱动程序和编程软件。在本例中,压缩包中的"CH341A_1.30"很可能是编程软件的安装程序。安装后,用户可以通过软件界面选择需要编程的芯片类型,加载待烧录的固件或数据,然后执行编程操作。编程过程中需要注意的是,确保正确设置芯片的电压、时钟频率等参数,以防止损坏芯片。 CH341A编程器1.3版是面向电子爱好者和专业工程师的一款实用工具,其强大的兼容性和易用性使其在众多编程器中脱颖而出。对于需要处理25Q256等32M芯片的项目,或者26系列芯片的编程工作,CH341A编程器是理想的选择。通过持续的软件更新和升级,它保持了与现代电子技术同步,确保用户能方便地对各种芯片进行编程和调试。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值