2019-2020-1 20199305《Linux内核原理与分析》第九周作业
进程的切换和一般执行过程
(一)进程调度的时机
(1)关键问题
何为进程切换?就是进程调度时机到来时从就绪进程队列中能够挑选一个进程执行,占用CPU时间,那么就有两个关键问题:一是什么时间去挑选一个就绪进程(调度时机);而是如何让进程占用CPU(进程切换的过程)?
(2)硬中断与软中断
-
硬中断(Interrupt)就是CPU的两根引脚(可屏蔽中断和不可屏蔽中断)。CPU在执行每条指令后检测两根引脚的电平,如果是高电平,说明有中断请求,CPU就会中断当前程序的执行后去处理中断。一般类似时钟/键盘/硬盘等外设都是以这种方式与CPU进行信号传递的。
-
软中断(Exception)也被称为异常,其包括除零错误/系统调用/调式断点等在CPU执行指令过程中的发生的各种特殊情况统称为异常,异常会导致程序无法继续执行,而跳转到CPU预设的处理函数。异常包括故障/退出/陷阱三种。
(3)进程调度时机
1)schedule函数
Linux内核通过schedule函数实现进程调度,它在运行队列中找到一个进程,把CPU分配给它。所以调用该函数一次就是调度一次,调用该函数的时机就是进程调度的时机。调用schedule函数的两种方法如下:
-
进程主动调用schedule(),如进程调用阻塞的系统调用等待外设或者主动睡眠。
-
松散调用,内核代码可以随时根据需要调用schedule使当前内核路径让出CPU。
2)上下文
一般来说,CPU在任何时刻都处于以下三种情况之一:
-
运行于用户空间,执行用户进程上下文。
-
运行于内核空间,处于进程上下文。
-
运行于内核空间,处理中断上下文。
3)进程调度的时机
-
用户进程通过特定的系统调用主动让出CPU。
-
中断处理程序在内核返回用户态时进行调度。
-
内核线程主动调用schedule函数让出CPU。
-
中断处理程序主动调用schedule函数让出CPU。
(二)Linux系统的运行过程
(1)Linux的一般执行过程
1)正在运行的用户态X。
2)发生中断(包括异常、系统调用)。
3)保护现场,此时完成上下文切换。
4)中断处理过程中或中断返回前调用schedule函数,其中switch_to做了关键进程上下文切换。
5)运行用户态进程Y。
6)恢复现场。
7)完成中断上下文切换,从进程Y内核态返回到进程Y的用户态。
8)继续运行用户态进程Y。
(2)几种特殊情况
1)通过中断处理过程中的调度时机,用户态进程与内核线程之间互相切换和内核线程之间互相切换,与最一般的情况非常类似,只是内核线程运行过程中发生中断没有进程用户态和内核态的转换;
2)内核线程主动调用schedule(),只有进程上下文的切换,没有发生中断上下文的切换,与最一般的情况略简略;
3)创建子进程的系统调用在子进程中的执行起点及返回用户态,如fork;
4)加载一个新的可执行程序后返回到用户态的情况,如execve;
(3)Linux整体框架和执行过程
(4)进程调度相关代码跟踪实验
1)在虚拟机环境中打开一个shell命令窗口,运行MenuOS系统
2)通过增加-S -s启动参数打开调试模式,命令如下:
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -S -s
3)另外开一个shell命令窗口进行gdb调试并设置断点
4)打开gdb,设置断点,其中switch_to为宏定义,不能设置断点,需到context_switch函数中单步执行查看调用
-
schedule函数断点
-
pick_next_task函数断点
-
context_switch函数断点
-
switch_to函数断点