1 组调度
1.1 进程调度基础
操作系统为了协调多个进程的同时运行,最基本的手段就是给进程设定优先级,如果有多个进程处于可执行状态,那么优先级高的进程先被调度执行。
Linux内核将进程分为两种级别,普通进程和实时进程,实时进程的优先级高于普通进程,另外他们的调度策略也不同。
实时进程的调度
1、如果一个进程是实时进程,只要它是可执行状态的,内核就一直让它执行,以尽可能满足它对cpu的需要,直到进程执行完成,睡眠或退出(不可执行状态)。
2、如果有多个进程一直处于可执行状态,则内核会先满足优先级最高的实时进程对cpu的需求,直到这个进程执行完成变成非可执行状态。
这样,如果高优先级的实时进程一直处于可执行状态,低优先级的实时进程就一直不能得到cpu;只要一直有实时进程处于可执行状态,普通进程就一直不能得到cpu。明显不能达到多任务的效果。
所以内核中通过/proc/sys/kernel/sched_rt_runtime_us和/proc/sys/kernel/sched_rt_period_us两个参数来控制在sched_rt_period_us为周期的时间内,实时进程最多只能运行sched_rt_runtime_us这么多时间,这样留给普通进程一定的运行时间。
3、如果有多个相同优先级的实时进程处于可执行状态,有两种调度策略可以选择
SCHED_FIFO:先进先出。直到先被执行的进程变为非可执行状态,后来的进程才被调度执行。在这种策略下,先来的进程可以执行sched_yield系统调用,自愿放弃CPU,以让权给后来的进程;
SCHED_RR:轮转调度。内核为实时进程分配时间片,在时间片用完时,让下一个进程使用CPU;
实时进程的调度是比较简单的,进程的优先级和调度策略都由用户设定,内核总是选择优先级最高的实时进程来调度执行。在选择具有相同优先级的实时进程时,要考虑两种调度策略。
普通进程的调度
普通进程没有实时的需求,调度器力图让每个处于可执行状态的进程平分cpu时间,从而让用户认为这些进程是同时进行的。
普通进程的调度中,内核要关注动态调整进程的优先级和进程调度的公平性两方面。
1、动态调整优先级
进程按照行为可以分为交互式进程和批处理进程,交互式进程较批处理进程有较高的优先级。但系统正常运行场景下,用户并不会完全设置交互式进程和批处理进程的优先级。于是内核中通过调度程序来区分这些进程的优先级,调度程序关注进程近一段时间内的表现(主要是检查其睡眠时间和运行时间),根据一些经验性的公式,判断它现在是交互式的还是批处理的?程度如何?最后决定给它的优先级做一定的调整。
进程的优先级被动态调整后,就出现了两个优先级:
1)、用户程序设置的优先级(如果未设置,则使用默认值),称为静态优先级。这是进程优先级的基准,在进程执行的过程中往往是不改变的;
2)、优先级动态调整后,实际生效的优先级。这个值是可能时时刻刻都在变化的;
2、调度公平性
在支持多进程的系统中,理想情况下,各个进程应该是根据其优先级公平地占有CPU。而不会出现“谁运气好谁占得多”这样的不可控的情况。
linux实现公平调度基本上是两种思路:
1)、给处于可执行状态的进程分配时间片(按照优先级),用完时间片的进程被放到“过期队列”中。等可执行状态的进程都过期了,再重新分配时间片;
2)、动态调整进程的优先级。随着进程在CPU上运行,其优先级被不断调低,以便其他优先级较低的进程得到运行机会;
后一种方式有更