【操作系统篇】白话讲Linux进程如何被CPU调度

白话讲Linux进程如何被CPU调度

前言

CPU调度分为主动式调度和抢占式调度。其实通常不采用主动式调用,而是采用抢占式调用;
举例:先有一块CPU,然后有a进程和b进程启动;

主动式调用

它们是交替执行CPU,进程a执行一段时间就让出CPU,就调CPU提供的api,在该函数内部实现切换给另一进程执行

切换就是把当前上下文,也就是CPU的一堆寄存器值保存到进程的控制块,然后CPU把另一进程的上下文寄存器值装载起来,开始执行。

主动调用是取决于当前进程是否调用api,让出CPU给另一个进程执行,但往往没那么听话,进程在执行时发生死循环等操作,不主动调用让出CPU的api;

抢占式调用

利用时钟中断,一旦有中断事件过来,CPU就会执行中断处理程序,只要在时钟中断处理函数里添加调度入口,就可以抢到CPU的执行权。
为了公平起见,CPU让进程执行一小段时间,称为时间片,每个进程执行的时间片,让就绪队列存储起来,排队依次执行。如果队列中有些进程在sleep或wait等待锁,防止它们占用cpu空转,即使它们时间片还没用完,也要让出CPU,并把它们放到另一个队列中去,这就是等待队列,等到执行条件满足,例如sleep的时间够了,或获取到锁,就把它重新放到就绪队列中去。

如果进程数太多,CPU根据时间片轮着执行每个进程,每个进程执行时间片的执行时间又有点长,导致用户感知某个进程的执行时间久,该怎么办呢
此时就要为进程设置优先级,CPU先执行优先级高的进程,但没理由都放在同一个就绪队列中,难道每次调度时就遍历就绪队列吗,这样导致时间复杂度为O(n)。
于是将就绪队列划分为40个优先级队列,先执行优先级高的队列,判断对应优先级队列是否有进程,是通过一个位图bitmap来判断,如果位图为0,代表该队列没进程需要执行,为1代表队列有进程需要执行。

但是又有一个问题,由于高优先级的进程存在,低优先级很难有机会执行,除非高优先级的进程在睡眠或等待,否则没机会被执行,此时该怎么办
各个优先级的进程放到对应的优先级队列中,执行完时间片的进程会放到一个expire队列中,原来的优先级队列是active队列,当active队列的进程执行完之后,就将这两个队列的指针互换,避免队列内存拷贝,继续从active队列中获取进程执行。

优先级高的进程应该分配长一些的时间片执行
于是每个优先级队列的进程获取到的时间片多不一样,优先级高的获取的时间片长一些,例如多5ms,优先级1的队列进程时间片为5ms,优先级2的队列进程时间片为10ms,按照分配给这两个优先级的调度概率来说,优先级进程1,就5/(5+10)=33.3%,优先级进程2,就是10/(5+10)=66.7%,调度概率差的有点大。

于是使用相对时间来获取时间片:
比如设定调度周期为固定时间,例如100ms,让所有进程来划分这100ms,这样每个进程获取的时间片,按优先级来分,计算公式为:

划分的时间片是有最小时间限制的

优先级高的,权重就高,这里是每个优先级的权重:
在这里插入图片描述
还有一个问题,调度的时候如何挑选下一个进程呢?

如果有些进程由于睡眠或等待锁让出CPU,在调度时就应该要得到补偿,一旦符合执行条件,就优先被执行,主动放弃CPU的进程,它们执行时间肯定比分配的短,要不按进程运行时间来排序,挑选执行时间最短的来执行?

但每个进程因优先级分配的时间长短不一,如果可以消除因权重带来分配时间长短不一的影响,就可以用运行时间来排序,于是弄一个虚拟的运行时间,把权重带来的影响给修复回去,比如优先级高的进程,分配的时间多,统计它运行时间的时候,就让它流逝地慢一些,统计优先级低的进程,分配的时间少,统计时间的时候,就让它流逝地快一些,这样进程在没有睡眠、等待、io的时候,大家都是用完了自己的时间,消除权重后的虚拟时间都是一样,都是调度时间的1/N,这就公平了,这样让所有进程按虚拟时间来排序,排在前面的虚拟时间短,下一个就调度它。

那在调度下一个进程,关于数据结构,应该如何选择?

在这里插入图片描述

使用的是红黑树,根据每个进程的虚拟时间来组成一棵红黑树,只要找到整棵树最左边的节点,就是要运行的进程,为了更高效,树调整更新时候因为需要维持红黑树的四个原则时会导致最左节点发生变化,于是把它缓存起来,这样调度时候就能直接拿到这个缓存节点。

关于上面使用白话一步步推论,实际举例的参数是有些许出入的,实际使用概念如下图:
在这里插入图片描述

若有错漏的,欢迎各位看官在评论区指出哈!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值