1. 调度时机
调度时机一般可以分成两类:主动调度和强制调度。
1.1 主动调度
-
在形式上一般是这样的:
内核在等待资源的时候,将当前进程移到等待队列,并主动调用schedule()放弃CPU;
-
主动调度的例子:
read()系统调用,会调用到wait_on_sync_kiocb(),其中有这么一段
while (iocb->ki_users) { set_current_state(TASK_UNINTERRUPTIBLE); if (!iocb->ki_users) break; schedule(); }
大致就是,资源还未准备的话,就主动调用schedule()放弃CPU;
1.2 强制调度
-
在形式上一般是这样的:
-
在系统调用 / 中断处理中设置TIF_NEED_SCHED;
-
系统调用返回用户态 / 中断返回(可能返回内核态)前,
检查TIF_NEED_SCHED(中断返回内核态还要检查preempt_count),
如果进行了设置,则在返回前调用schedule();
-
-
强制调度的例子:
-
IO中断的例子,
阻塞read()的IO资源读取完成,进入中断处理。
在中断处理中,调用try_to_wake_up()的封装函数,设置TIF_NEED_SCHED;
中断返回后(假设是返回到用户态),检查到TIF_NEED_SCHED被设置,调用schedule();
-
时钟中断的例子,
在时钟中断的中断处理中,调用scheduler_tick(),
最简单的情况是当普通进程的时间片耗尽后,设置TIF_NEED_SCHED;
中断返回后(假设是返回到用户态),检查到TIF_NEED_SCHED被设置,调用schedule();
-
系统调用的例子,
信号机制中,想发送信号到某个进程时,
-