实验四:内核线程管理
实验2/3完成了物理和虚拟内存管理,这给创建内核线程(内核线程是一种特殊的进程)打下了提供内存管理的基础。当一个程序加载到内存中运行时,首先通过ucore OS的内存管理子系统分配合适的空间,然后就需要考虑如何分时使用CPU来“并发”执行多个程序,让每个运行的程序(这里用线程或进程表示)“感到”它们各自拥有“自己”的CPU。
本次实验将首先接触的是内核线程的管理。内核线程是一种特殊的进程,内核线程与用户进程的区别有两个:
- 内核线程只运行在内核态
- 用户进程会在在用户态和内核态交替运行
- 所有内核线程共用ucore内核内存空间,不需为每个内核线程维护单独的内存空间
- 而用户进程需要维护各自的用户内存空间
实验目的:
- 了解内核线程创建/执行的管理过程
- 了解内核线程的切换和基本调度过程
实验内容:
练习0:
本次实验依赖之前lab1,lab2以及lab3的内容,用meld工具对比,复制文件即可,这里不再过多赘述。
练习1:分配并初始化一个进程控制块
alloc_proc函数(位于kern/process/proc.c中)负责分配并返回一个新的struct proc_struct结构,用于存储新建立的内核线程的管理信息。ucore需要对这个结构进行最基本的初始化,完成这个初始化过程。
首先我们在proc.h中查看进程的数据结构proc_struct
下面对参数进行简单的讲解:
(1) mm:内存管理的信息,包括内存映射列表、页表指针等。
(2) state:进程所处的状态。
(3) parent:用户进程的父进程(创建它的进程)。
(4) kstack:记录了分配给该进程/线程的内核桟的位置。
(5) need_resched:是否需要调度
(6) context:进程的上下文,用于进程切换
(7) tf:中断帧的指针
(8) cr3: cr3 保存页表的物理地址
设计实现:
需要初始化的proc_struct结构中的成员变量至少包括:state/pid/runs/kstack/need_resched/parent/mm/context/tf/cr3/fl