【操作系统】实验:进度调度(2)

news2024/12/23 14:49:48

目录

一、实验目的

二、实验要求

三、实验步骤

四、核心代码

五、记录与处理

六、思考

七、完整报告和成果文件提取链接


一、实验目的

1、掌握高优先权调度算法

2、理解时间片、优先权、抢占等基本概念。

二、实验要求

1. 优先权属于静态优先权;

2. 进入 CPU 运行一个时间片;

3. 考虑事先给定优先权和短进程优先两种情况;

4. 考虑到达时间不同。

三、实验步骤

1. 创建多个进程,假定所有进程都是就绪状态,根据进程的到达时间进就绪队列,选择调度算法;

2. 按照所选调度算法,使进程在就绪队列中排序,队列中队头进程优先级最高,队尾优先级最低;

3. 初始状态直接让队头进程进 CPU,运行 1 个时间片;

4. 如果进程在 CPU 上运行时间和服务时间相等,则该进程不需进就绪队列,否则,进程进就绪队列;同时,根据进程的到达时间看是否有进程进就绪队列;

5. 每次调度时都要输出一次所有进程信息。

四、核心代码

void CopyProgram(PCB *pro1,PCB *pro2) {
	memcpy(pro1->name,pro2->name,sizeof(pro2->name));
	pro1->arrivetime=pro2->arrivetime;
	pro1->running_time=pro2->running_time;
	pro1->priority=pro2->priority;
	pro1->start_time=pro2->start_time;
	pro1->done_time=pro2->done_time;
	pro1->zztime=pro2->zztime;
	pro1->dqzztime=pro2->dqzztime;
}
 
void Queueinit(PCBQueue* queue) {
	if (queue == NULL) {
		return;
	}
	queue->size = 0;
	queue->LastProg = (PCB*)malloc(sizeof(PCB));
	queue->LastProg->next=NULL;//注意加了此句
	queue->firstProg = queue->LastProg;
}
 
void EnterQueue(PCBQueue* queue, PCB* pro) {
	//加入进程队列
	queue->LastProg->next = (PCB*)malloc(sizeof(PCB));
	queue->LastProg = queue->LastProg->next;
	queue->LastProg->arrivetime = pro->arrivetime;
	memcpy(queue->LastProg->name, pro->name, sizeof(pro->name));
	queue->LastProg->priority = pro->priority;
	queue->LastProg->running_time = pro->running_time;
	queue->LastProg->copyRunning_time = pro->copyRunning_time;
	queue->LastProg->start_time = pro->start_time;
	queue->LastProg->next=NULL;//注意加了此句
	queue->size++;
}
 
PCB* poll(PCBQueue* queue) {
	PCB *temp;
 
	temp = queue->firstProg->next;
	if (temp == queue->LastProg) {
		queue->LastProg = queue->firstProg;
		queue->LastProg->next=NULL;//注意加了此句
		queue->size--;
		return temp;
	}
	queue->firstProg->next = queue->firstProg->next->next;
	queue->size--;
 
	return temp;
}
 
void sortWithEnterTime(PCB pro[], int num) { //将进程按到达时间(arrivetime)全部排序
	int i,j;
	PCB temp;
 
	for (i = 1; i < num; i++) {
		for (j = 0; j < num - i; j++) {
			if (pro[j].arrivetime > pro[j + 1].arrivetime) {
				temp = pro[j];
				pro[j] = pro[j + 1];
				pro[j + 1] = temp;
			}
		}
	}
}
 
void EnterQueueOfRuntime(PCBQueue *ready_queue,PCB *program) { //按进程的运行时间,找到就绪队列中的相应位置并插入进去
	PCB *p,*q;
	p=ready_queue->firstProg->next;
	q=ready_queue->firstProg;
 
	while(p) {
		if(p->running_time>program->running_time) {
			program->next=p;
			q->next=program;
			break;
		}
		q=p;
		p=p->next;
	}
	if(!p) { //如果就绪队列为空或该进程的运行时间最长,则将其插入到队尾
		ready_queue->LastProg->next=program;
		ready_queue->LastProg=program;
		program->next=NULL;
	}
	ready_queue->size++;
}
 
void EnterQueueOfPriority(PCBQueue *ready_queue,PCB *program) {
	PCB *p,*q;
	p=ready_queue->firstProg->next;
	q=ready_queue->firstProg;
 
	while(p) {
		if(p->priority<program->priority) { //优先级大的先执行
			program->next=p;
			q->next=program;
			break;
		}
		q=p;
		p=p->next;
	}
	if(!p) {
		ready_queue->LastProg->next=program;
		ready_queue->LastProg=program;
		program->next=NULL;
	}
	ready_queue->size++;
}
 
void FCFS(PCB pro[], int num) {
	int time,done_time;
	int i,count,tt,pronum;
	float sum_T_time,sum_QT_time;
	PCB *curpro,*temp_PCB;
 
	printf("\n\t\t\t\t\t先来先服务算法进程调度模拟\n\n");
	printf("\t————————————————————————————————————————————————\n");
	count=0;
	PCB pro2[100];
	sortWithEnterTime(pro, num);                              //按照进入到达时间顺序排序
	PCBQueue* queue = (PCBQueue*)malloc(sizeof(PCBQueue));    //定义就绪队列
	Queueinit(queue);                                        //就绪队列初始化
	EnterQueue(queue, &pro[0]);                              //将第一个进程送入就绪队列中
	time = pro[0].arrivetime;                            //记录第一个进程的到达时间
	pronum = 1;                                          //记录当前的进程数量
	sum_T_time = 0, sum_QT_time = 0;                   // sum_T_time 记录总的周转时间 ,sum_QT_time 记录总的加权周转时间
	while (queue->size > 0) {
		curpro = poll(queue);                           //从进程队列中取出一个进程
		if (time < curpro->arrivetime){
			time = curpro->arrivetime;
		}
		done_time = time + curpro->running_time;               //  done_time   为该进程的结束时间(开始时间+CPU运行时间)
		curpro->start_time=time;
		curpro->done_time=done_time;
		curpro->zztime = done_time - curpro->arrivetime;//周转时间
		curpro->dqzztime = curpro->zztime / curpro->running_time;//带权周转时间              
		sum_T_time += curpro->zztime;                                      //  sum_T_time  总的周转时间更新
		sum_QT_time += curpro->dqzztime;                                     //  sum_T_time  总的带权周转时间更新
		for (tt = time; tt <= done_time && pronum < num; tt++) { //模拟进程的执行过程
			if (tt >= pro[pronum].arrivetime) {
				EnterQueue(queue, &pro[pronum]);
				pronum++;
			}
		}
		CopyProgram(&pro2[count],curpro);
		PrintRunningprogram(&pro2[count]);
		count++;
		if(queue->size!=0) {
			printf("\t就绪队列:\n");
			printf("\t————————————————————————————————————————————————\n");
			printf("\t进程 到达时间  服务时间 优先级\n");
			temp_PCB=queue->firstProg->next;
			for(i=queue->size; i>0; i--) {
				printf("\t%s\t%d\t%d\t%d\n",temp_PCB->name,temp_PCB->arrivetime,temp_PCB->running_time,temp_PCB->priority);
				temp_PCB=temp_PCB->next;
			}
			printf("\t————————————————————————————————————————————————\n");
			printf("\n\n\n");
		} else {
			printf("\t无进程处于就绪状态!\n");
			printf("\t————————————————————————————————————————————————\n\n\n");
		}
		time += curpro->running_time;
		if (queue->size == 0 && pronum < num) {
			//防止出现前一个进程执行完到下一个进程到达之间无进程进入
			EnterQueue(queue, &pro[pronum]);
			pronum++;
		}
	}
	PrintSortOfRunningprogram(pro2,count);
	//Print(pro2,count);
	printf("\t平均周转时间为:%.2f\n", sum_T_time /num);
	printf("\t平均带权周转时间为:%.2f\n",sum_QT_time/num);
}

主函数代码:

int main() {
	int n, t = 1;
	int proNum,  choice;
	PCB pro[MAXSIZE],temp_pro[MAXSIZE];
 
	printf("\n\n\t\t\t\t\t<<-------------进程初始化----------——>>\n");
	printf("\t\t\t\t\t请输入进程的个数:");
	scanf("%d", &proNum);
	inputProgram(pro, proNum);
	while (t) {
		menu();
		memcpy(temp_pro, pro, (sizeof(pro) / sizeof(pro[0])) * sizeof(PCB));
		scanf("%d", &n);
		while (n <= 0 || n > 4) {
			printf("\t\t\t指令不正确,请重新输入指令: ");
			scanf("%d", &n);
		}
		system("cls");
		switch (n) {
			case 1: {
				FCFS(temp_pro, proNum);
				break;
			}
			case 2: {
 
				SJF(temp_pro, proNum);
				break;
			}
			case 3: {
				HPF(temp_pro, proNum);
				break;
			}
			case 4: {
				t=0;
				break;
			}
		}
		getchar();
		printf("\n\t按任意键继续.......");
		getchar();
		system("cls");
	}
	system("cls");
	printf("\n\n\t\t\t\t\t您已成功退出系统!!!\n");
 
	return 0;
}

五、记录与处理

输入的进程数据如下:

选择第三个:高优先级算法

按照高优先级进行输出结果:

六、思考

高优先权调度算法的弊端是什么?

高优先权调度算法是一种在计算机系统中用于进程或作业调度的算法,它根据进程的优先权(或优先级)来决定执行顺序。优先权高的进程或作业会被优先执行,而优先权低的则会被推迟执行。然而,这种算法也存在一些弊端:

1.低优先级进程饥饿:在高优先权调度算法下,如果系统中存在大量高优先级的进程,低优先级的进程可能会被持续推迟执行,导致它们的响应速度变慢,甚至长时间得不到执行,这种现象被称为“饥饿”。

2.恶意进程或病毒的影响:恶意进程或病毒可能会通过提高自己的优先权来占用系统资源,导致正常进程无法得到执行。这种情况下,系统的安全性和稳定性会受到影响。

3.可能导致系统资源浪费:如果高优先级的进程执行了很短的时间就放弃处理机,那么系统会频繁地进行进程切换,这会导致系统资源的浪费,降低系统的整体效率。

4.未考虑作业的紧迫程度:高优先权调度算法在决定执行顺序时,可能未充分考虑作业的紧迫程度,因此不能保证紧迫性作业会被及时处理。

为了克服这些弊端,可以采用一些优化措施,例如设置进程的最大执行时间以避免长时间占用CPU资源,或者采用动态优先级调度算法,根据进程的实际执行情况来动态调整进程的优先级。此外,还可以考虑引入高响应比优先调度算法,以更全面地考虑进程的执行需求。

综上所述,虽然高优先权调度算法能确保高优先级进程或作业得到优先处理,但也存在可能导致低优先级进程饥饿、受恶意进程或病毒影响、系统资源浪费以及未考虑作业紧迫程度等弊端。因此,在设计和实施此类算法时,需要充分考虑这些因素,并采取适当的优化措施。

七、完整报告和成果文件提取链接

链接:https://pan.baidu.com/s/1UbP6729pCluscVW0_9oI8w?pwd=1xki 
提取码:1xki 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2077184.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DevOps实现CI/CD实战(五)- Jenkins流水线Pipeline-更新中..

九、 Jenkins流水线pipeline Jenkins流水线任务介绍 之前采用Jenkins的自由风格构建的项目&#xff0c;每个步骤流程都要通过不同的方式设置&#xff0c;并且构建过程中整体流程是不可见的&#xff0c;无法确认每个流程花费的间&#xff0c;并且问题不方便定位问题。Jenkins的…

工程数学与数学建模在编程与算法设计中的应用(下)

目录 引言 第三部分&#xff1a;工程数学在算法设计与优化中的应用 3.1 微分方程与动力系统模拟 常微分方程&#xff08;ODE&#xff09;在动态系统中的应用 偏微分方程&#xff08;PDE&#xff09;在图像处理与物理模拟中的应用 总结 3.2 概率论与数理统计在机器学习中的…

若依将登录用户的userId自动加载到查询中

点击搜索&#xff0c;会将登录用户的userId作为搜索条件&#xff0c;去查询。 新版本自动存储了userId&#xff0c;我们不用改&#xff0c;只要知道如何引用。 前端使用 在对应的vue文件&#xff0c;查询queryParams 加查询的值 然后参考他的 添加store import store from &…

i.MX6裸机开发(11)——DDR测试

本章参考资料&#xff1a;《IMX6ULRM》(参考手册)。 学习本章时&#xff0c;配合《IMX6ULRM》Chapter 33: Multi Mode DDR Controller (MMDC) 一起阅读&#xff0c;效果会更佳&#xff0c;特别是涉及到寄存器说明的部分。 特别说明&#xff0c;本书内容是以i.MX6U系列控制器资…

Serdes系统中的CTLE技术

典型的SerDes系统包含输入数据、串行器、发射机&#xff08;TX&#xff09;、信道、接收机&#xff08;RX&#xff09;、解串器和输出数据。串行数据比特流被输入到发送器。发射机由均衡器&#xff08;EQ&#xff09;和包括封装效果的线性模拟后端组成。传输后端和接收器前端之…

JAVA语言开发环境配置详细讲解

​ ​ 您好&#xff0c;我是程序员小羊&#xff01; 前言 Java是一门广泛应用于软件开发领域的编程语言&#xff0c;自1995年由Sun Microsystems首次发布以来&#xff0c;经过多年的发展&#xff0c;已经成为业界的重要编程语言之一。Java以其“编写一次&#xff0c;到处运行”…

【计算机网络】电路交换、报文交换、分组交换

电路交换&#xff08;Circuit Switching&#xff09;&#xff1a;通过物理线路的连接&#xff0c;动态地分配传输线路资源 ​​​​

IDEA/Pycharm/Goland/jetbrains2024.2全家桶汉化失败问题解决

近期,jetbrains全家桶更新到了2024.2版本,不少人反馈到,下载安装之后,按照以前的汉化方式进行汉化的之后,并没有生效。本章教程,提供此问题的解决方案,亲测有效。 JetBrains 是一家总部位于捷克布拉格的软件开发公司,成立于 2000年。该公司以开发高效、智能的开发工具和…

基于SparkGraphX实现标签传播(LPA)算法

基于SparkGraphX实现标签传播&#xff08;LPA&#xff09;算法 标签传播算法&#xff08;LPA&#xff09;与Louvain一样&#xff0c;同样是一种常用的社群发现算法&#xff0c;它的基本思想是让图中的节点根据邻居节点的标签&#xff08;即社区信息&#xff09;来更新自己的标…

第J1周:ResNet-50算法实战与解析(TensorFlow版)

>- **&#x1f368; 本文为[&#x1f517;365天深度学习训练营]中的学习记录博客** >- **&#x1f356; 原作者&#xff1a;[K同学啊]** 本周任务&#xff1a; 1.请根据本文TensorFlow代码&#xff0c;编写出相应的pytorch代码 2.了解残差结构 3.是否可以将残差模块融…

Mybatis的搭建以及使用

一&#xff0c;如何搭建Mybatis 1&#xff0c;创建一张表和表对应的实体类 2.导入 MyBatis jar 包,mysql 数据库驱动包 <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.2</version> …

ICML 2024 顶级论文:机器学习有什么新进展?

在本周的文章中&#xff0c;我打算探讨在国际机器学习大会 ICML 上发表的论文&#xff0c;该大会目前于 2024 年 7 月 21 日至 27 日在奥地利首都维也纳举行。与其他顶级人工智能会议一样&#xff0c;每年都会有数千篇论文提交&#xff0c;但录取率相对较低&#xff08;过去三年…

JavaScript高阶 day-02

目录 一.构造函数 1.1 JS构造函数的实例成员和静态成员 1.1.1实例成员 1.1.2静态成员 1.2构造函数原型prototype 1.3对象原型 1.4 constructor构造函数 1.5原型链 1.6构造函数实例和原型对象三角关系 1.7原型链和成员的查找机制 1.7.1 Object.prototype.hasOwnPrope…

正高职称评审中专利与论文的权重比较

正高职称评审中&#xff0c;专利和论文的权重因地区、行业、单位以及具体评审政策的不同而有所差异。 一般来说&#xff0c;专利分不同类型&#xff0c;包括发明专利、实用新型专利和外观设计专利。发明专利申请授权过程中要进行实质审查&#xff0c;含金量最高&#xff0c;在…

通过ClearScript V8在.NET中执行复杂JavaScript逻辑

介绍 在现代网络开发中&#xff0c;爬虫技术已成为数据采集和分析的核心手段之一。通常&#xff0c;爬虫程序需要处理复杂的JavaScript逻辑&#xff0c;尤其是在面对动态加载的网页时。这时&#xff0c;传统的HTTP请求和HTML解析已经无法满足需求。为了应对这些挑战&#xff0…

高清无水印,2024年最佳免费录屏工具集合

如果你喜欢记录游戏的精彩瞬间&#xff0c;那班迪录屏你一定不陌生吧&#xff0c;它是一款主攻游戏录制的工具&#xff0c;这次我们一起来探索下除了它之外还有什么工具能实现我们电脑录屏操作呢。 1.福昕REC大师 链接&#xff1a;www.foxitsoftware.cn/REC/ 这个软件我推荐…

深度学习——分布式训练

目录 1. 前言2.分布式训练的分类3.不并行&#xff08;单机单卡&#xff09;4. 数据并行 DP和DDP4.1 异同点4.2 原理4.3 DP 实现&#xff08;单机多卡&#xff09;4.4 DDP 实现&#xff08;单机多卡&#xff0c;多机分布式&#xff09;4.4.1DDP 基本概念4.4.2 DDP之单机多卡4.4.…

知识付费小程序搭建

近期&#xff0c;我的一位教育培训机构的朋友巧妙运用了一款知识付费小程序&#xff0c;成功解锁了教育创新的新篇章。这个月&#xff0c;他的教学平台迎来了显著的增长&#xff0c;新增生源高达200人&#xff0c;这一成就令人瞩目。他巧妙地将线上教学的便捷性与线下互动的沉浸…

一个php快速项目搭建框架源码,带一键CURD等功能

介绍&#xff1a; 框架易于功能扩展&#xff0c;代码维护&#xff0c;方便二次开发&#xff0c;帮助开发者简单高效降低二次开发成本&#xff0c;满足专注业务深度开发的需求。 百度网盘下载 图片&#xff1a;

汉服文化平台网站

您好&#xff01;本篇论文将详细介绍汉服文化平台网站的设计与实现&#xff0c;该项目基于Java语言&#xff0c;采用SSM框架&#xff0c;结合MySQL数据库完成开发。如果您对汉服文化或本项目有任何兴趣或疑问&#xff0c;欢迎随时与我联系。 开发语言 Java 数据库 MySQL 技…