进程、系统调用和进程调度

进程、系统调用和进程调度
进程是操作系统最重要的概念之一,实际上,实现进程之前的部分都不能被称为操作系统 。进程的切换和调度等内容是和保护模式的相关技术紧密相连的,而这也是本书作者要花大量篇幅先介绍保护模式的原因,但是,对于一个只学过微机原理和C语言的小白(比如我)来说,理解起来还是太难了 。为此,我特意先学习了保护模式相关的知识,具体书籍和路径前面已经介绍过 。
“对于进程的概念,只有在有了基于具体平台的感性认识之后,才有可能对形而上的理论有更踏实的理解”,对作者的这句话我深以为然 。其实不单单是进程的概念,对于计算机领域的无数理论概念来说都一样,各种抽象的理论和概念没有落脚点,朦胧的理解就会很快被遗忘,而这个落脚点其实就是具体的实现,这和那句著名的“源码之下,了无秘密”的道理其实是一致的 。“有了一种机型的经验,不但有利于在学习理论时形成形象思维,更有触类旁通的能力,面对任何类型的机器和操作系统都能够胸有成竹 。”
进程介绍
作者的这段关于进程的讲解也十分符合他的理念,将进程涉及的代码数据和堆栈以及对进程的调度这些抽象的概念与具体的人做工作的行为对应起来,给抽象的概念以具体的例子支撑 。看过很多对进程的讲解都是为了举例子而举例子,看完还是无法将进程理解清楚 。

进程、系统调用和进程调度

文章插图
多进程的必要准备
多进程下,处于内存中的进程数总是大于CPU数的
graph LR进程数大于CPU数-->进程有运行和挂起等不同状态进程有运行和挂起等不同状态-->内核要对各个进程进行调度在不同状态间切换内核要对各个进程进行调度在不同状态间切换 -->切换时需要保存和恢复进程运行状态切换时需要保存和恢复进程运行状态--> 采用数据结构来保存进程状态
几个设计点明确最简单的进程(包含涉及的关键技术) 进程调度过程 进程A运行时钟中断发生,ring1->ring0,进入中断处理程序调用进程调度模块,获取切换的目标进程B切换到(恢复)进程B,ring0->ring1进程B运行 关键技术先进行ring0->ring1——启动第一个用户进程
准备工作有:进程表,进程体,GDT和TSS
进程表和GDT的创建和设置:这里因为LDT也是进程的一部分,所以方便起见也把LDT放在了进程表PCB里,同时还放了LDT的选择子 。然后在GDT里放置进程的LDT描述符 。进程表和进程 。进程表是进程的描述,储存了进程的各个寄存器的值,暂时为了简单起见,只放必须的,比如进程的入口地址,另外,由于堆栈是由内核设置的,不受程序本身控制,所以还需要指定esp 。GDT和TSS 。在GDT里创建进程对应TSS的描述符 。注意点
一定要记得以下几点:
进程启动过程总结
进程、系统调用和进程调度

文章插图
第二步,开始使用时钟中断——通过中断回到内核ring0多进程
前面已经为多进程打好了基础,可以从内核跳转到第一个进程运行,运行的进程可以被中断,中断完成后还能返回到原来的进程恢复运行 。
添加新的进程体
在main.c函数里加一个TestB()函数 。
实现批量准备进程4要素的相关变量和宏进程表初始化代码扩充(用for批量处理)
每次循环从TASK中读取不同任务的入口地址、堆栈栈顶和进程名(这里进程和任务等价)
两个注意点:
批量生成进程的LDT
在()里用for循环批量
修改中断处理程序——添加进程切换代码