基于Bootstrap的h5简单模拟CPU调度算法

版权声明:醋姑娘 https://blog.csdn.net/weixin_37023469/article/details/84172885

一、说明

模拟了下面四种CPU调度算法

  1. FCFS,先到先服务
  2. SRTF,抢占式最短剩余时间优先
  3. RR,轮询
  4. 抢占式优先级

实验要求

  1. gantt图
  2. 计算每个进程的等待时间
  3. 计算平均等待时间
  4. 考虑CPU空闲的情况

其他

  1. 前端使用了Bootstrap框架,因为时间紧迫而且确实效果还行。
  2. github地址:https://github.com/cuguniang/CPU_Schedual

二、实现效果

  1. 进程信息
    在这里插入图片描述

  2. FCFS
    在这里插入图片描述

  3. SRTF
    在这里插入图片描述

  4. RR
    在这里插入图片描述

  5. 优先级
    在这里插入图片描述
    在这里插入图片描述

  6. CPU空闲的情况
    在这里插入图片描述

在这里插入图片描述

三、实现时的一些思考

  1. 用户添加的顺序 != CPU调度的顺序,需要重新排序,而希望进程列表中显示的顺序仍是用户输入的顺序,所以在实现调度前,先深拷贝用户输入的数组。
    在这里插入图片描述

  2. gantt图使用彩色块看起来效果更好,本来想在一个大div里塞小div,但很丑。决定用bs的进度条组件,这是用bs框架的最重要的原因!但具体实现的时候,其实还是往大div里塞小div,只不过这里的div具有bs的class。
    gantt图效果:
    在这里插入图片描述
    对应的html:
    在这里插入图片描述

  3. 学会用array的sort和比较函数了,如下

scheual_process.sort(function (a, b) {
	//到达时间一样,短作业优先
	if(a.arrival_time == b.arrival_time){
		return a.CPU_brust - b.CPU_brust;
	}
	//否则按到达时间排序
	return a.arrival_time - b.arrival_time;
});	
  1. 希望每段进程的CPU区间颜色不同,采用bs提供的progress-bar-xxx类,xxx=primary|warning|error|sucess|info,分别具有不同的颜色,一开始随机获取数组中一个值,作为每段的颜色。但是相邻的两段有时候就会颜色相同,于是就按顺序循环取:希望每段进程的CPU区间颜色不同,采用bs提供的progress-bar-xxx类,xxx=primary|warning|error|sucess|info,分别具有不同的颜色,一开始随机获取数组中一个值,作为每段的颜色。但是相邻的两段有时候就会颜色相同,于是就按顺序循环取:
var COLOR = {	
	color:["primary","warning","success","danger","default","info"],
	index:0
			};
function getColor(){
	return COLOR.color[(COLOR.index++)%COLOR.color.length];
}
  1. 抢占实在是太难写了。当前进程结束时,如果没有别的进程,它就空闲,否则选择一个剩余时间最短的进程来执行;如果没执行完,一个新的进程就来到了,判断它的剩余时间和新进程的剩余时间,新进程更短的话,就抢占。最外层循环条件是:
while(scheual_process.length>0 || ready_queue.length>0){
	...
	//多种情况
	1. CPU空闲
	2. now_p结束时next_p还未到达 => ready_queue中还有没有进程?
	3. 刚好在结束时到达 => 加入ready_queue一起排序
	4. 未结束时到达,可能抢占 => 比较剩余时间
}
  1. 写了两个类,Process用来调度,Bar用来绘制gantt图
function Process(process_name,arrival_time,CPU_brust,priority) {
	this.process_name = process_name;
	this.arrival_time = arrival_time;
	this.CPU_brust = CPU_brust;
	this.priority = priority;
	this.remaining_time = CPU_brust;
	this.waiting_time = 0;
	this.start_time = 0;
	this.end_time = 0;
	return this;
}

function Bar(name,start,end,color){//for gantt
	this.name = name;
	this.start = start;
	this.end = end;
	this.color = color;

	return this;
}

附:利用Bar的对象数组bars来绘制gantt,包括下面的数字

function process_painter(bars,total_brust){
	for(var i = 0;i < bars.length;i++){
		var num = $("<span></span>");
		var bar = $("<div></div>").addClass("progress-bar");

		bar.addClass("progress-bar-"+bars[i].color);//进程颜色
		bar.text(bars[i].name);//进程名字
		bar.css('width',((bars[i].end-bars[i].start)/total_brust*100)+"%");//进程比例
		$("#gantt").append(bar);

		num.text(bars[i].end);
		num.css('width',(bars[i].end-bars[i].start)/total_brust*100-0.5+"%");
		$("#gantt_num").append(num);		
	}
}

在每个调度算法中往bars里添加元素,如

bars.push(new Bar(p.process_name,now_time,now_time+time_q,getColor()));

最后调用process_painter()方法即可

process_painter(bars,now_time);

  1. 如果一个进程分开执行了多次,每次等待时间就不能用now_time-减去arrival_time。要考虑是不是第一次执行到它,而且每次调度时,要更新它的start_time和end_time。(SRTF中代码如下)
if(now_p.CPU_brust == now_p.remaining_time){//第一次执行到它
	now_p.start_time = now_time;
	now_p.waiting_time += now_p.start_time - now_p.arrival_time;
}
else{
	now_p.waiting_time = now_time - (now_p.end_time-now_p.start_time);
	now_p.start_time = now_time;
}			
  1. 被array的splice方法坑死(最开始还拼错了),第一个参数是index,最终改成这样才能把这个执行完的now_p给移除。
ready_queue.splice(ready_queue.indexOf(now_p),1);
  1. 优先级就是把SRTF的实现复制过来,改了抢占的条件和一点点细节(比如对remaining_time的处理)。实际上抢占式的优先级就是一般化的SRTF,SRTF的原则是剩余时间短 = 优先级高,而优先级是直接给了个数值代表优先级。注意small int ≡ high priority

四、反思

  1. Process类的定义应该从PCB的结构出发来考虑。
  2. 切换进程时,应该写一个类似切换上下文的函数。把对各种时间的设置写进函数里。

猜你喜欢

转载自blog.csdn.net/weixin_37023469/article/details/84172885
今日推荐