调度程序运行时,要在所有处于可运行状态的进程之中选择最值得运行的进程投入运行。选择进程的依据是什么呢?在每个进程的task_struct结构中有这么五项:
need_resched、nice、counter、policy 及rt_priority
(1) need_resched: 在调度时机到来时,检测这个域的值,如果为1,则调用schedule() 。
(2)counter: 进程处于运行状态时所剩余的时钟滴答数,每次时钟中断到来时,这个值就减1。当这个域的值变得越来越小,直至为0时,就把need_resched
域置1,因此,也把这个域叫做进程的“动态优先级”。
(3 )nice: 进程的“静态优先级”,这个域决定counter 的初值。只有通过nice(),
POSIX.1b sched_setparam() 或 5.4BSD/SVR4 setpriority()系统调用才能改变进程的静态优先级。
(4) rt_priority: 实时进程的优先级
(5) policy: 从整体上区分实时进程和普通进程,因为实时进程和普通进程的调度是不同的,它们两者之间,实时进程应该先于普通进程而运行,可以通过系统调用sched_setscheduler(
)来改变调度的策略。对于同一类型的不同进程,采用不同的标准来选择进程。对于普通进程,选择进程的主要依据为counter和nice 。对于实时进程,Linux采用了两种调度策略,即FIFO(先来先服务调度)和RR(时间片轮转调度)。因为实时进程具有一定程度的紧迫性,所以衡量一个实时进程是否应该运行,Linux采用了一个比较固定的标准。实时进程的counter只是用来表示该进程的剩余滴答数,并不作为衡量它是否值得运行的标准,这和普通进程是有区别的。
这里再次说明,与其他操作系统一样,Linux的时间单位也是“时钟滴答”,只是不同的操作系统对一个时钟滴答的定义不同而已(Linux设计者将一个“时钟滴答”定义为10ms)。在这里,我们把counter叫做进程的时间片,但实际上它仅仅是时钟滴答的个数,例如,若counter为5,则分配给该进程的时间片就为5个时钟滴答,也就是5*10ms=50ms,实际上,Linux2.4中给进程初始时间片的大小就是50ms