2021-10-24

4.进程调度

4.1多任务

多任务操作系统:能并发执行多个进程
抢占式:可以强制性挂起一个进程
非抢占式:不可挂起

I/O消耗性和处理器消耗性的进程

I/O消耗进程多数时间用来等待文件输入,运行时间很少,处理器消耗反之

4.2 linux 调度算法

linux调度器Schedule()选择最优的拥有进程的调度类,调度类schedule()再选择最优的进程运行,进程运行的时间取决于它被分配到的时间片的多少
进程优先级:nice值来设置优先级(-20~19)默认是0,值越大优先级越低
时间片:进程被强占前可运行时间
CFS(公平调度):大多数普通进程都用CFS策略调度,CFS没有时间片的概念,而是根据目标延迟值/进程的数量计算出处理器分配的份额,nice会成为处理器分配的权重,每个进程分配到的份额都相等,但处理器使用比也是可变的,当进程使用cpu的时间远小于被分配的份额时,另一些进程会抢占此进程,重新计算这个使用比;
这里有一个问题就是当进程无限多时,处理器使用比会趋于0,从而内核忙于调度,因此设置一个时间片底线(最小粒度)为1ms

linux调度的实现

4.5.1时间记账

每一个时钟节拍会使得时间片减少一个节拍周期,当节拍周期减到0时,它会被其他进程抢占
CFS里使用调度器实体结构来记账,它的实体结构被放在进程描述符里
viruntine变量:虚拟运行时间,记录一个程序运行了多长时间,相关函数计算

4.5.2进程选择

挑选viruntine最小的进程作为最大优先级,CFS使用红黑树管理进程,最左叶子节点是最大优先级的进程,进程堵塞或终止时从红黑树删除,陷入等待时被标记成休眠状态,加入等待队列并设置成不可执行状态,再从红黑树中删除,事件发生时再改为可运行状态,再把它加入运行队列,再从等待队列删掉
need_reached描述符表示是否需要重新调度

4.6.1 用户抢占

系统调用/中断处理程序要返回用户空间的时,会检查need_reached,如果设置了,就会重新调度

4.6.2 内核抢占

1.中断处理程序正在执行,且返回内核空间之前
2.内核代码再一次拥有可抢占性
3.内核任务显示(阻塞也会导致)调用schedule()

实时调度策略

就是比某进程优先级高的进程才可以抢占它
SCHED_FIFO没有时间片,而SCHED_RR带有时间片
软实时:进程时间片用完前可能被抢占
硬实时:不会被抢占

4.8与调度相关的系统调用

4.8.2处理器绑定

可以通过设置位掩码(保存在进程task_struct标志中)指定某进程只能在哪些cpu上运行,每一位标志着一个处理器,子进程继承了父进程的位掩码

4.8.3 放弃处理器时间

sched_yield()系统调用可把某进程调为最小优先级,并放入过期队列,确保其一段时间不会被执行