目录
进程分类
有两种传统的分类法:
方法一
- CPU密集
- I/O密集
方法二
- 交互 (比如记事本)
- 批处理 (比如后台、编译器进程)
- 实时
进程抢占
进程是可抢占的,在新的进程进入TASK_RUNNING状态,表示可以运行的时候,内核会检查他们的动态优先级。如果比当前的进程优先级高就调用调度器进行调度。
调度算法和调度类
普通进程的调度
基础时间片的计算
时间片不是每个进程都一样的。是根据静态优先级算出来的。
优先级越高时间片越长。
动态优先级和平均睡眠时间
动态优先级会在静态优先级的基础上根据前一段时间统计的平均睡眠时间进行小幅度调整。
平均睡眠时间长,内核认为这个进程可能是交互式进程。会抬高它的动态优先级。
实际的调度是按照动态优先级调度的。
实时进程调度
每个实时进程都与实时优先级相关联,其值范围从1(最高优先级)到99(最低优先级)。调度程序总是倾向于高优先级的可运行进程,而不是低优先级的进程;换句话说,是实时的进程在保持可运行时抑制每个低优先级进程的执行。
同优先级FIFO RR并存
Linux 提供了两种实时调度策略,SCHED_FIFO 和 SCHED_RR。正常的非实时调度策略是 SCHED_NORMAL。 SCHED_FIFO 实现了一个简单的没有时间片的先进先出调度算法。一个可运行的 SCHED_FIFO 任务总是调度在任何 SCHED_NORMAL 任务之上。当 SCHED_FIFO 任务变为可运行时,它会继续运行,直到它阻塞或显式让出处理器;它没有时间片,可以无限期地运行。只有更高优先级的 SCHED_FIFO 或 SCHED_RR 任务可以抢占 SCHED_FIFO 任务。具有相同优先级的两个或多个 SCHED_FIFO 任务循环运行,但同样仅在它们明确选择这样做时才让出处理器。如果 SCHED_FIFO 任务是可运行的,则所有优先级较低的任务在完成之前都无法运行。 SCHED_RR 与 SCHED_FIFO 相同,只是每个进程只能运行到它用完预定的时间片。也就是说,SCHED_RR 是带有时间片的 SCHED_FIFO,它是一种实时循环调度算法。当 SCHED_RR 任务耗尽其时间片时,任何其他处于其优先级的实时进程都将被调度轮询。时间片仅用于允许重新安排相同优先级的进程。与 SCHED_FIFO 一样,高优先级的进程总是立即抢占低优先级的进程,而低优先级的进程永远不能抢占 SCHED_RR 任务,即使它的时间片已用尽。
只有当发生以下事件之一时,实时进程才会被另一个进程取代:
- 该进程被具有更高实时优先级的另一个进程抢占。
- 该进程执行阻塞操作,并将其置于休眠状态(状态为TASK_可中断或TASK_UNINTERRUPTIBLE)。
- 进程停止(状态为TASK_STOPPED或TASK_TRACED),或被终止(状态为EXIT_ZOMBIE或EXIT_DEAD)。
- 该进程通过调用sched_yield()系统调用来自愿放弃CPU(请参见本章后面的“与调度相关的系统调用”部分)。
- 这个过程是实时循环(SCHED_RR),它已经耗尽了它的时间片。