目录
关于queue[140]前100个位置 | 实时进程与分时进程
回顾进程优先级与进程调度的引入
在我们之前的学习中,我们是有学习过进程优先级这个概念的,这里简单回顾一下
默认优先级是80,但是还有一个nice值可以供我们修改优先级的值
这是因为:优先级 = 默认优先级 + nice值
而nice值的范围是从-20~19,也就是说,进程优先级是有40个值的,即从60 ~ 99
但是现在进程的优先级我们知道了,而在系统之中,他是如何使用这些优先级的呢?
内核runqueue图例
如下图:
这个是我们内核中的runqueue,前面我们在进程状态那篇博客中也有提到他,只要进程被链入runqueue之中,就代表他会被CPU调度执行,也就是就绪和运行状态
并且,一个CPU只有一个runqueue
而今天我们将会详细谈一谈runqueue里面的几个字段,因为我们今天要讲调度,那就必然和这些绕不开
首先是上图中用蓝色框框框起来的,第三个,也就是queue[140]
需要说明的是,这140个空间中,前100个是给实时进程的(后文会有所举例),也就是0~99位置,而后面的100~139这40个位置
不对,40个位置,这和我们的nice值的范围,也就是进程优先级的范围不是正好吻合了吗!
事实也的确如此,我们来看一下图例:
我们的每一个下标,在这样子分布的情况下,就可以和进程的优先级一一对应,而我们这时候如果有进程进来了,那么就会直接根据他的优先级进行插入到相应位置:
比如这样,接着就能够调度起来了
关于queue[140]前100个位置 | 实时进程与分时进程
可能很多同学对这几个字眼比较陌生,这里举一个例子就明白了
分时操作系统就好比我们的电脑,需要同时让多个进程进行轮转,同时运行
而实时操作系统则像是车子,一台汽车里面可能有很多功能,音乐、影视等等,但是总不能说有紧急情况了,现在我要刹车,结果操作系统说:不行,我音乐还在放呢,你不能刹车,这也太扯了
以上就是关于实时操作系统和分时操作系统的讲解,这里并不打算详说,因为今天的重点是动态理解进程的调度
遍历需要调度的进程与bitmap的引入
首先,我们并不是所有进程的优先级都是从60开始的,大部分甚至都是80
那问题来了,我们前面还有100个空间没有使用,空着放在那里给实时进程准备着,那我们每一次要找下一个需要调度的进程的时候,都需要一个一个去找吗?这样的话效率太低了
所以runqueue中还有一个东西,叫做bitmap[5],也就是所谓的位图:
至于为什么是 5 呢,因为5*32=160,而4*32=128,5 个可以刚好覆盖,但是4个则会直接不够
而我们有了位图之后,效率的提升是明显的
比如我们现在要看前32个空间有没有进程,我们只需要这样:
bitmap[i]==0
这样我们一次就能知道32个位置有没有进程,如果为0,那就下一个32,如果不为0,那再一个一个找进程
active、expired指针
active(活跃)expired(过期)
我们现在再来看回最开始那张图片:
我们可以看到,这里面其实有两个框,蓝和红两个,并且,里面的内容是完全一样的
在看到蓝色框框上面的两个变量,那是两个指针,active 和 expired,而这两个指针指向的就是下面的两个框框
我们再通过画图来理解一下这个过程:
在最开始的时候,进程在活跃(active)指针指向的queue下面,等到调度完之后
这个进程就会被链入到expired所指向的queue中(下图用蓝色框框表示的就是已经调用结束的进程):
而所有的进程在被调度完之后,上面active指针所指向的queue,直接遍历 1 次bitmap,发现全是 0,就知道全部调度完了
接下来就是:两个指针的值直接交换(swap(*active, *expired))
这样我们的活跃queue和过期queue就完成了交换
接下来就是继续调度active指针指向的进程,全部执行完了之后,就再交换,过期的重新变成活跃的
如此往复
结语
这篇文章到这里就结束啦!!~( ̄▽ ̄)~*
如果觉得对你有帮助的,可以多多关注一下喔