Hammy学习操作系统-进程调度

1,313 阅读9分钟

调度

当计算机系统是多道程序系统时,通常就会有多个进程或线程同时竞争CPU。只要有两个或更多的进程处于就绪状态,这种情形就会发生。如果只有一个CPU可用,那么就必须选择下一个要运行的进程.在OS中,完成选择工作的这一部分就是称为调度程序(Scheduler),改程序所有的算法调度算法。

1.1 调度简介

在网络服务器中,经常出现多个进程竞争CPU,因此调度功能再一次至关重要。在移动设备中,电池是瓶颈。

另外,为了选取正确的进程运行,调度程序还要考虑CPU的利用率,因为进程切换的代价是比较高的。

1.1.1 进程行为

几乎所有进程的IO请求和计算都是交替突发的。典型地,CPU不停顿地运行一段时间,然后发出一个系统调用以便读写文件.在完成系统调用之后,CPU继续计算。

一般随着CPU变得越来越快,进程更倾向于IO密集型,这种现象之所以发生是因为CPU的改进比磁盘快很多。

1.1.2 何时调度

有关调度处理的第一个关键问题是何时进行调度决策。存在着需要调度处理的各种情形。

  • 在创建一个新进程后,先运行子进程还是父进程。由于这两种进程都处于就绪状态,所以这是一个正常的调度决策。也就是说,调度程序可以合法选择先运行父进程还是子进程。
  • 在一个进程退出时,必须做出调度决策。一个进程不再运行,所以必须从就绪进程集中选择另外某个进程。如果没有就绪的进程,通常系统会运行一个系统提供的空闲进程。
  • 当一个进程阻塞IO和信号量上或由于其他原因阻塞时,必须选择另一个进程运行。有时,阻塞的原因会成为选择的因素。
  • 在一个IO中断时,必须做出调度决策。如果中断来自IO设备,而该设备现在完成了工作,某些被阻塞的等待该IO的进程就成为可运行的就绪进程了。

如果硬件时钟提供50Hz、60Hz或其他频率的周期性中断,可以在每k个时钟中断时做出调度决策。如果处理时钟中断,可以把调度算法分为两类,非抢占式和抢占式。

  • 非抢占式调度算法挑选一个进程,然后该进程运行直至被阻塞,或者进程自动释放CPU
  • 抢占式调度算法挑选一个进程,让该进程运行某个固定时段的最大值。如果该时段结束,进程扔运行,它就被挂起,调度程序挑选另一个进程运行。

1.1.3 调度算法的分类

不同的环境需要不同的调度算法。之所以出现这种情形,是因为不同的应用领域。

  • 批处理:在批处理系统中,一般不会有用户不耐烦地在终端旁等待一个短请求的快捷响应。因此,非抢占算法,对于每个进程都有长时间周期的抢占式算法,通过是可以接受的。
  • 交互式:为了避免一个进程霸占CPU拒绝为其他进程服务,抢占是必须的。即使没有进程想永远执行,但是,某个进程由于一个程序错误也可能无限期排斥其他所有进程。

1.1.4 调度算法的目标

在所有的情形中,公平是很重要的。相似的进程应该得到相似的服务。另一个目标是,保持系统的所有部分尽可能忙碌。在批处理系统中,在批处理系统中既运行一些CPU密集,又运行一些IO密集比分别运行更好。

运行批量作业的指标:

  • 吞吐率,每小时完成的作业数量
  • 周转时间,作业开始到完成的平均时间
  • CPU利用率

对于交互式系统来说,最重要的是响应时间。

1.2 批处理系统中的调度

1.2.1 先来先服务

在所有调度算法中,最简单的是非抢占式的先来先服务。使用该算法,进程按照它们请求CPU的顺序使用CPU。基本上,就一个就绪进程的单一队列,按照时间顺序执行。当其他作业执行时,它们被排到就绪队列尾部。当正在运行的进程被阻塞时,就绪队列中的第一个接着运行。当被阻塞进程恢复时,就像一个新来到的作业一样,排到就绪队列的末尾。

优点:

易于理解

缺点:

适合计算密集型,不适合IO密集型,因为被阻塞在恢复就要回到队列的尾部.

1.2.2 最短作业优先

最短CPU运行期优先调度算法,该算法丛就绪队列中选出一个cpu执行期最短的进程,分配给CPU.

优点:

良好的调度性能,充分利用cpu

缺点:

难以准确知道下一个CPU执行周期,而只能根据每个进程的执行历史进行预测。

1.3 交互式系统中的调度

1.3.1 轮转调度

最简单和公平使用最广的就是轮转调度。每个进程被分配一个时间段,称为时间片,即允许改进程在时间段运行。时间片结束,剥夺CPU并分配给另一个进程。如果该进程在时间片结束前阻塞或结束,则cpu立刻切换。

时间片的长度要适中,不能太长会太短。太短会引起太多的进程切换,太长会引起轮转到的请求速度太慢。

优点:

真正意义上实现了公平

缺点:

如果一个进程需要立刻执行,如飞机系统中,飞机进行降落。也需要等待时间片的分配

1.3.2 优先级调度

每一个进程被赋予一个优先级,允许优先级最高的可运行进程先运行。

可以动态确定优先级,例如,进程为IO密集型,其多数时间来等待IO结束。当这样的进程需要cpu时,应立即分配给它cpu,以便启动下一个io请求。

优点

可以让优先级高的or关键进程进行先使用cpu

缺点

低优先级进程可能存在饥饿的情况

1.3.3 多级队列

多级反馈队列方式是在系统中设置多个就绪队列,并赋予各队列以不同的优先权。

在优先级调度上进行了细化,针对不同的场景给予不同的时间片,减少进程切换的次数。但仍然面临低优先级进程的问题

1.4 策略和机制

以上的调度算法中,没有一个算法从用户进程接受有关调度决策信息,这就导致了调度程序很少能做出最优选择。

解决问题的办法是将调度机制与调度策略分离这个一贯的原则。也就是将调度算法以某种形式参数化,而参数可以由用户进程填写。假设内核使用优先级调度算法,并提供一条可供设置优先级的调用。这样,尽管父进程并不参与调度,但它可以控制如何调度子进程的细节。在这里,调度机制位于内核,而调度策略由用户进程决定。策略和机制分离是一种关键思路。

1.5 线程的调度

当若干进程都有多个线程时,就存在两个层次的并行:进程和线程。在这样的调度处理有本质差别,取决于支持的是用户线程还是内核级线程。

首先考虑用户级线程。由于内核并不知道有线程存在,所以内核还是和以前一样操作,选择一个进程,假设为A,并给予A时间片控制。A中的线程调度程序决定哪个线程运行。这个线程运行的时间就是进程的全部时间片,内核再选择另一个进程运行.

轮转算法和优先级算法是os中最常用的进程调度算法.

内核级线程,选择一个特定的线程运行,它不用考虑线程属于哪个进程,不过有必要的话,它可以这么做。对被选择的线程赋予一个时间片。

用户级线程和内核级线程之间的差别在于性能。用户级的线程切换需要少量的机器指令,而内核的线程需要完成的上下文切花,修改内存映像,让告诉缓存失效,这导致了若干数量级的延迟。另外,内核级线程在IO阻塞时,不需要将整个进程挂起

内核进程的切换,会根据进程之间的关系进行考量。如从进程A的一个线程切换到进程B的一个线程,一定没有切换到进程A的另一个线程更有效。

一般而言,应用定制的线程调度程序能够比内核更高满足应用需要。主要原因是内核本身不了解每个线程的应用。

1.6 Linux中的进程调度器

Linux在内核2.6以后开始,就使用CFS作为进程的调度器。在CFS之前, 使用的是O(1)和O(n)调度算法。这两种算法,基本思路都是通过一系列运行指标确定进程优先级,根据进程优先级进行调度。而CFS,它不计算优先级,而是通过计算进程消耗的CPU时间(标准化以后的虚拟CPU时间)来确定谁来调度,从而达到公平性。

绝对公平性

cfs定义了一种新的模型,其基本思路很简单,他把CPU当做一种资源,并记录下每一个进程对改资源的使用情况,在调度时,调度器总是选择消耗资源最少的进程来原型。这就是所谓的"完全公平",但这种绝对的公平有时也是一种不公平,因为有些进程的工作比其他进程更重要,所以需要权重来分配CPU资源。

相对公平性

为了区别不同优先级的进程,就是会根据各个进程的权重分配运行时间。 分配给进程的运行时间 = 调度周期 * 进程权重 / 所有进程权重之和

针对Linux中的进程调度后续进行补充...

引用

www.jianshu.com/p/673c9e481…

book.douban.com/subject/139…

baike.baidu.com/item/%E8%BF…