diff --git a/study/kernel/01-process/05-schedule/01-introduction/README.md b/study/kernel/01-process/05-schedule/01-introduction/README.md index 8ddd3bf..cc0859e 100644 --- a/study/kernel/01-process/05-schedule/01-introduction/README.md +++ b/study/kernel/01-process/05-schedule/01-introduction/README.md @@ -197,3 +197,32 @@ linux进程的调度算法其实经过了很多次的演变, 但是其演变主 * 在选中将要运行的进程之后, 必须执行底层的任务切换. 这需要与CPU的紧密交互. 每个进程刚好属于某一调度类, 各个调度类负责管理所属的进程. 通用调度器自身不涉及进程管理, 其工作都委托给调度器类. + +#进程的调度 +------- + +首先,我们需要清楚,什么样的进程会进入调度器进行选择,就是处于TASK_RUNNING状态的进程,而其他状态下的进程都不会进入调度器进行调度。 +系统发生调度的时机如下 + +* 调用cond_resched()时 + +* 显式调用schedule()时 + +* 从系统调用或者异常中断返回用户空间时 + +* 从中断上下文返回用户空间时 + +当开启内核抢占(默认开启)时,会多出几个调度时机,如下 + +* 在系统调用或者异常中断上下文中调用preempt_enable()时(多次调用preempt_enable()时,系统只会在最后一次调用时会调度) + +* 在中断上下文中,从中断处理函数返回到可抢占的上下文时(这里是中断下半部,中断上半部实际上会关中断,而新的中断只会被登记,由于上半部处理很快,上半部处理完成后才会执行新的中断信号,这样就形成了中断可重入) + +而在系统启动调度器初始化时会初始化一个调度定时器,调度定时器每隔一定时间执行一个中断,在中断会对当前运行进程运行时间进行更新,如果进程需要被调度,在调度定时器中断中会设置一个调度标志位,之后从定时器中断返回,因为上面已经提到从中断上下文返回时是有调度时机的,在内核源码的汇编代码中所有中断返回处理都必须去判断调度标志位是否设置,如设置则执行schedule()进行调度。 + +而我们知道实时进程和普通进程是共存的,调度器是怎么协调它们之间的调度的呢,其实很简单,每次调度时,会先在实时进程运行队列中查看是否有可运行的实时进程,如果没有,再去普通进程运行队列找下一个可运行的普通进程,如果也没有,则调度器会使用idle进程进行运行。 + +之后的章节会放上代码进行详细说明。 + +系统并不是每时每刻都允许调度的发生,当处于硬中断期间的时候,调度是被系统禁止的,之后硬中断过后才重新允许调度。而对于异常,系统并不会禁止调度,也就是在异常上下文中,系统是有可能发生调度的。 +