当前位置: 首页 > news >正文

操作系统实验一模拟优先级调度算法(C语言实现附带详细注释)

文章目录

优先级调度算法介绍

两种情况

调度算法分类

优先级分类

实验内容与要求

实验步骤

调度算法总流程图

 优先级调度算法流程图

 实验代码

实验结果


优先级调度算法介绍

        优先级调度算法既可以用于作业调度,又可以用于进程调度。该算法中的优先级用于描述作业或者进程的紧迫程度,主要思想是每次选取优先级最高的进程或者作业,将资源或者处理机分配给它使用。

两种情况

  • 在作业调度中,优先级调度算法每次从后备作业队列中选择优先级最高的一个或者几个作业,将它们存入调入内存,分配必要的资源,创建进程并放入就绪队列。
  • 在进程调度中,优先级调度算法每次从就绪队列中选择优先级最高的进程,将处理机分配给它,使之投入运行。

调度算法分类

根据新的更高优先级进程能否抢占正在执行的进程,可将该调度算法分为两类:

1)非抢占式优先级调度算法

        当一个进程正在处理机上运行时,即使有某个优先级更高的进程进入就绪队列,仍让正在执行的进程继续执行下去,直到因为其自身的原因(任务完成或者发生等待事件),这才把处理机的使用权分配给其它优先级更高的进程

2)抢占式优先级调度算法

        顾名思义,当有一个优先级更高的进程进入就绪队列时,立即暂停正在执行的进程,将处理机的使用权分配给优先级更高的进程,等其执行完毕方可继续执行本进程

优先级分类

 根据进程创建后其优先级是否可以改变,可以将进程优先级分为一下两类:

1)静态优先级

        优先级是在创建进程时就已经被确定的,且在进程运行的整个期间保持不变。主要根据进程类型、进程对资源的要求、用户的要求来确定静态优先级

2)动态优先级

        在进程的运行过程中,根据进程情况的变化动态调整优先级。主要根据进程占有CPU时间的长短、就绪进程等待CPU时间的长短来确定动态优先级


实验内容与要求

        进程是操作系统最重要的概念之一,进程调度是操作系统内核的重要功能,本实验要求用C语言编写一个进程调度模拟程序,使用优先级或时间片轮转法实现进程调度。本实验可加深对进程调度算法的理解。实验内容如下:

  • 设计有5个进程并发执行的模拟调度程序,每个程序由一个PCB表示。
  • 模拟调度程序可选择优先级调度算法或者时间片轮转调度算法
  • 程序执行中应能在屏幕上显示出各进程的状态变化
  • 使用C/C++语言进行模拟 

实验步骤

调度算法总流程图

 优先级调度算法流程图

 实验代码

进程控制块PCB结构体如下:

typedef struct pcb{
	int id;//进程的ID
	int prior;//进程的优先级,允许为负,规定:-20表示进程已完成
	int used;//已经使用的时间片
	int need;//还需要的时间片
	char status;//进程的状态  R,J,F分别表示进程正在运行、进程就绪、进程完成 
}PCB;

完整代码:

/*
操作系统,进程调度算法的模拟
按照优先级算法进行进程调度 
*/ 
#include"stdio.h"
#include"conio.h"
#include"stdlib.h"
#include<ctime>
//定义进程控制块PCB的结构体
typedef struct pcb{
	int id;//进程的ID
	int prior;//进程的优先级
	int used;//已经使用的时间片
	int need;//还需要的时间片
	char status;//进程的状态  R,J,F分别表示进程正在运行、进程就绪、进程完成 
}PCB;
PCB *head,p[5];

//打印显示输出进程
void print(){
	printf("-----------------------------------------------------\n");
	printf("进程ID\t优先级\t已使用的时间片\t还需时间片\t状态\n");
	for(int j=0;j<5;j++){
		printf("%d\t  %d\t  %d\t\t  %d\t\t %c\n",p[j].id,p[j].prior,p[j].used,p[j].need,p[j].status);
	}
} 

//使用冒泡算法按照优先级降序排列
void sort(){
	for(int i=0;i<5;i++){
		for(int j=0;j<4;j++){
			if(p[j].prior<p[j+1].prior){
				PCB temp=p[j];
				p[j]=p[j+1];
				p[j+1]=temp;
			}
		}
	}
} 

//初始化进程队列
void inputprocess(){
	srand(time(0));//为随机数产生种子
	 //依次先为每一个进程p[i]初始化 
	for(int i=0;i<5;i++){
		p[i].id=i+1;
		p[i].prior=1+rand()%5;//生成1~5的随机数作为各个进程的优先级
		p[i].used=0;
		p[i].need=1+rand()%5;//总时间片 
		p[i].status='J';//初始化为就绪态 
	} 
	sort();//按照优先级进行排序
	head=p;
	printf("开始进程的状态:\n");
	print();//打印进程的状态 
} 

按照最高优先级优先调用来调用进程队列
void runprocess(){
	PCB *p1=NULL;
	do{
	  p1=head;
	  head=p+1;
	//根据优先级调度原则,判断队列的队首进程是否能够运行
	while(p1->need>0&&p1->prior>=head->prior){
		p1->need--;
		p1->prior--;
		p1->status='R';
		p1->used++;
		print();
	}
	//如果进程总的时间片已经用完,一律将其进程的优先级设置为-20,状态为已完成
	if(p1->need==0){
		p1->prior=-20;
		p1->status='F';
	} else{
		p1->status='J';
	} 
	sort();//再次排序为下一次运行做准备
	head=p;
    }while(head->prior!=-20);
    print();
	printf("-----------------------------------------------------\n");
	printf("所有的进程已执行完毕!");
}
int main(){
	inputprocess();
	runprocess();
	return 0;
}

实验结果

 

另外,模拟时间片轮转算法可以看一下这篇文章:模拟时间片轮转算法

看完了吧,记得点赞哦!(doge)

相关文章:

  • 【基础知识】tiff格式图片介绍及读取
  • 基于图搜索的规划算法之可视图法
  • 【python】之哥德巴赫猜想(递归法)和教室排课(枚举法)
  • 【基础教程】基于Matlab画花式箱体图
  • FPGA设计的10点小知识
  • SpringBoot Security 入门
  • STM32单片机PID控制数控恒流源-100mA~+100mA输出正负恒流源
  • Hadoop 3.x(生产调优手册)----【HDFS--核心参数】
  • Go Machine Learning
  • 【git】关于Git这一篇就够了
  • 什么 ? 陪玩都月入过忘拉~这不得python采集一下
  • 基于springboot服饰电商平台的设计与开发-计算机毕业设计源码+LW文档
  • 【STM32】硬件资源及芯片介绍
  • SpringMVC实现文件的上传和下载
  • Android 系统jni到hal层回调代码
  • 10个最佳ES6特性 ES7与ES8的特性
  • egg(89)--egg之redis的发布和订阅
  • FineReport中如何实现自动滚屏效果
  • Java,console输出实时的转向GUI textbox
  • Logstash 参考指南(目录)
  • oschina
  • Phpstorm怎样批量删除空行?
  • Yii源码解读-服务定位器(Service Locator)
  • 工作中总结前端开发流程--vue项目
  • 关于Java中分层中遇到的一些问题
  • 精彩代码 vue.js
  • 老板让我十分钟上手nx-admin
  • 浏览器缓存机制分析
  • 设计模式 开闭原则
  • 它承受着该等级不该有的简单, leetcode 564 寻找最近的回文数
  • 微信开源mars源码分析1—上层samples分析
  • 1.Ext JS 建立web开发工程
  • const的用法,特别是用在函数前面与后面的区别
  • 树莓派用上kodexplorer也能玩成私有网盘
  • ​LeetCode解法汇总2182. 构造限制重复的字符串
  • ​香农与信息论三大定律
  • !!java web学习笔记(一到五)
  • (145)光线追踪距离场柔和阴影
  • (4)STL算法之比较
  • (6)添加vue-cookie
  • (Demo分享)利用原生JavaScript-随机数-实现做一个烟花案例
  • (三)elasticsearch 源码之启动流程分析
  • (十五)Flask覆写wsgi_app函数实现自定义中间件
  • (转)【Hibernate总结系列】使用举例
  • (转)linux下的时间函数使用
  • (转)VC++中ondraw在什么时候调用的
  • (转)淘淘商城系列——使用Spring来管理Redis单机版和集群版
  • ./configure,make,make install的作用
  • .dwp和.webpart的区别
  • .NET Core 实现 Redis 批量查询指定格式的Key
  • .Net Framework 4.x 程序到底运行在哪个 CLR 版本之上
  • .NET 设计一套高性能的弱事件机制
  • .net通用权限框架B/S (三)--MODEL层(2)
  • .vue文件怎么使用_vue调试工具vue-devtools的安装
  • /proc/vmstat 详解