进程调度的时机
- 中断处理过程(包括时钟中断、I/O中断、系统调用和异常)中,直接调用schedule(),或者返回用户态时根据need_resched标记调用schedule();
- 内核线程可以直接调用schedule()进行进程切换,也可以在中断处理过程中进行调度,也就是说内核线程作为一类的特殊的进程可以主动调度,也可以被动调度;
- 用户态进程无法实现主动调度,仅能通过陷入内核态后的某个时机点进行调度,即在中断处理过程中进行调度
scheduel()函数分析
首先找到schedule()函数
在scheduel()中调用了_scheduel()
略过检查、统计、上锁等操作
直接看最关键部分的代码
2824行 从队列中取出下一个可运行的进程
接下来调用context_switch来进行实际的上下文切换。它是理解进程的切换的核心。它又调用switch_to来进行关键上下文切换。
找到switch_to 的代码
仔细阅读可以发现这和我们之前My_kernel实验中的代码十分相似
接下来用gdb跟踪schedule
跟踪过程中发生了一个意料之外的事情,进去_schedule中时,代码会先跳到context_switch 那里按n后又在__schedule开头处开始执行。
老师提供了一个ls的例子对于理解Linux的一般执行过程很有帮助