调度的定义
CPU并不只是简单的根据FIFO的规则来实现进程/线程的调度;
如何结合考虑进程/线程的优先级、运行时间等多方面的因素,实现合理、科学、高效得调度是本文要研究的核心内容;
如上图中,左侧是FIFO+优先级的综合调度,右侧是FIFO+运行时间的综合调度;
而所谓调度,就是从就绪队列中按照一定的算法选择一个进程/线程并将CPU等资源分配给它运行,已达到并发的效果;
调度的三个层次
高级调度:磁盘 -> 内存(只会调度一次,创建进程的过程)
磁盘上的程序软件可以有千千万万个(够大),但是内存相对磁盘而言,是相当有限的,一般内存就8G,没法同时存放磁盘上所有的软件,因此一般只会启动磁盘的一部分软件,即创建相应的进程,存储并运行在内存上;
磁盘上的作业提交后,等待被创建成新的进程(即,高级调度)磁盘上的某个软件程序以作业形式提交后,操作系统并不会立即就将其创建成新进程,作业的提交需要先进入磁盘中的作业等待队列中,CPU对这个等待队列中的作业以某种算法(通常思路是综合FIFO+优先级+***考虑因素)进行调度;所以我们平常使用Windows点击某个.exe软件时,界面上可能不会立马打开的软件窗口,可能需要等待一会软件才“启动响应”,这个过程其实就是新提交的创建进程的作业只是被放入等待队列中,还没有被CPU从队列中调度出来并执行作业;
这样的通过将作业提交至磁盘上的等待队列中,等待CPU调度并创建进程,然后将磁盘上的软件存储在内存的虚拟地址空间上,并由CPU取指执行的过程即是本小节讨论的“高级调度”;
高级调度:提交磁盘程序作业,等待创建新进程中级调度:磁盘->内存(会被调度多次,处于挂起态的进程重新调入内存的过程)
由于内存是稀缺资源,对于当前未处于运行态的某些进程,不能“占着茅坑不拉屎”,当前未处于运行态的进程被临时从内存置换到磁盘中,等待该进程再次具备运行条件或者内存有足够余量时,再重新调回内存;这样做能极大提升内存利用率和系统吞吐量;
这里的暂时将进程调到磁盘等待的进程状态,被称为挂起状态
(注:从这段话,我们可以稍作思考,进程的PCB和进程在内存中的虚拟地址空间,在逻辑上应该是设计成分开存放的,这样即便当进程的代码段、数据段等被置换到磁盘上,该进程的PCB并不会被置换出去,PCB仍旧在常驻内存中,虽然在内存中具体存放位置,我还不太清楚,但PCB应该还在就绪队列或者阻塞队列指向的某个内存地址上,这样的话,操作系统才可以继续对该进程进行管理,仍不会影响该进程在未来的某个时候可能会被分配CPU时间片,并重新获得CPU使用权)
注意这张图,虽然有两个进程从内存中被换到了磁盘中,但是与其对应的两个PCB依旧放在常驻内存上,接受操作系统的管理与调度;
上面介绍了什么是挂起态:因内存有限,当前不在运行的进程被暂时调到外存,此时进程的状态就是挂起态,即没在运行、又没有就绪或阻塞,更不是创建或终止;
而根据进程挂起之前的状态进行细分,可分为:就绪挂起、阻塞挂起;
不管是就绪挂起,还是阻塞挂起,都得是从磁盘重新调度到内存上,才能重新被运行;
五状态模型(未引入挂起态)七状态模型在七状态模型中,需要尤为注意的有:
- 存储在外存的阻塞挂起进程可以因时间的响应,直接在外存中转换成就绪挂起,因为都是挂起,所以进程依然是在外存上;
- 当进程刚用完时间片,可以直接从运行态,变成就绪挂起态;
- 当新的进程刚完成创建过程,可能也会直接进入就绪挂起;
而发生这一切的原因,基本都是因为内存不够用了
低级调度:即进程调度,从就绪队列中取出进程,将其转换成运行态(调度频率最高)
低级调度就是我们最常关注的多进程的管理与切换,即选择合适的算法从就绪队列中选取一个进程,并为其分配CPU等资源;
三个层次的调度对比:
操作系统调度总结