好 各位同学大家好
今天呢我们给大家介绍一下
lab5就是用户进程的管理
那这一部分呢 可以看到
我们主要讲以下几部分内容
第一个是总体介绍
大家知道我们这个实验
大致要完成什么样的功能
以及相应的一些总体的一些概述
第二个呢是
关于我们创建个用户进程
它的内存布局怎么回事
和我们前面讲有点不太一样
这是给大家做个介绍
第三个呢
我们既然要创建个用户进程
就需要执行一定的程序
那怎么能够把一个程序
放在进程里面去执行
这是这部分内容
以及我们说在原理课里面讲到
可以通过父进程创建子进程
那么具体这个进程复制
是怎么完成的
也会给大家做个介绍
最后一部分呢
是一个比较扩展一个内容
也是我们challenge的练习
就是怎么能够结合
内存管理的copy on write机制
来实现更有效的进程复制
这是我们这次总体
要介绍的一部分内容
首先看一下这个总体介绍
那么其实包含了
这次实验的目标练习和流程概述
那我们的目标是什么呢
其实我们希望通过这个练习呢
大家能够知道我们前面的三个实验
从lab1 2 3
那么是介绍了中断和内存管理
第四个实验已经有了内核线程
但是所有这些实验呢
都在什么地方呢
都是在内核空间里面来
完成各种各样的工程
还没有碰到像我们说
像这次实验课我们会提到什么
你要创建一个在用户态
执行的一个进程
那这个呢是
第一次我们的实验
从内核态跳到了用户态
那我们也就希望能够
把这个过程给大家展示出来
通过前面的lab1到lab4的工作呢
我们在lab空间里面
可以创建一系列的线程
最后来构造出一个用户态的进程
让它能够在用户空间去执行
这是说我们这次课希望达到一个目标
那把这个目标细化一下
我们这边要了解什么呢
第一个就是要了解一下
一个用户进程的创建过程
他怎么从零变到一的
从没有用户的进程到
存在用户进程怎么创建出来的
鸡和蛋怎么出现的
第二个呢是了解进程管理的实现
这里面主要是讲的是什么
主要是说我们怎么能够让
一个程序的内容能够
放到一个进程里面去执行
那这里面要了解什么是程序
什么是进程
它们之间的区别是什么
在原理课里面给大家做了介绍
那么通过实验呢
希望大家能够加强对
这两者之间的这个关系
和差别的理解
第三个是要了解
系统调用框架的实现
那这个和前面两个不太一样
前面两个需要大家去coding
需要去动手实验一下
那么对于最后这个呢
是大家是看一下
那么来看懂就OK了
相对来说我们的重点是放在前面
这个虽然很重要
因为通过系统调用呢
我们可以实现用户进程
得到内核的服务
但这一块呢
只要大家能看懂就OK了
因为对于系统调用的
这一部分的内容呢
其实和我们lab1中断管理呢
是有很紧密的联系的
它们有很大的一个相关性
但是也有一定的区别
那么你如果对lab1那个实验
有充分的了解之后呢
再看系统调用它的实现
其实是比较简单的
那我们在前面内容里面也讲到了
这个从一个特权级跳另一个特权级
怎么来完成呢
那其实也和我们这个
中断管理机制是相关的
那么大家可以回顾之前的一些工作呢
可以对此有更深入的理解
好 基于这个目标
我们要完成练习也是一样的
正好是说我们要去coding
去加载应用程序并执行
那么要去理解它大致
加载执行的这个过程怎么回事
然后完成我们需要完成的一个功能
第二个呢 我们要考虑一下
父进程怎么去复制子进程
这里面要考虑的一些细节问题呢
在原理课里面
可能涉及的比较少一点
我们希望通过实验呢
能够知道这里面的细节
是怎么来完成的
怎么来通过父进程
能够创建出一个子进程出来
第三个呢 是要分析系统调用
和进程管理的实现
因为我们知道我们的用户进程呢
它需要通过系统调用
来得到操作系统服务
这是一个 第二个呢
操作系统对进程本身也有管理
从最开始的创建到最后进程的消失
这有个生命周期的管理
在原理课里面也讲过
那我们会通过阅读代码呢
能对此有更深入体会
那我们的重点放在前面
前面是你怎么知道创建一个进程
当你知道怎么去创建一个进程之后呢
那么后续的一些工作
比如说进程状态的改变
相对来说比较简单一点
还有一个呢进程的卸载
比如说我们进程的离开退出
那么这个呢
相对来说就是
我们前面创建过程的一个逆过程
所以说也比较容易理解
这就是练习希望达到的目标
OK 那大家听起来好像感觉还不够
不知道到底跑什么程序
其实很简单
可以看到这个所谓的hello应用程序
和我们通常写的简单hello world很类似
没啥区别
这也是我们在ucore操作系统里面
支持跑的一个简单的应用程序
你可以看出来他干什么事情呢
一个main函数它就是打印字符串
第二个呢有系统调用叫getpid()
就得到当前它这个进程的ID信息
然后就退出了
从创建到最后return之后呢
我们的操作系统会把它给它kill掉
让它退出出去
那这里面就包含了系统调用
包含了创建一个基于
这个内容的一个用户进程
它的一个执行的一个状态的管理
以及最后生命周期一个管理退出
虽然这个程序很小
但是ucore操作系统呢
对它的管理是全面的
我们希望大家能够对这个
管理过程能够比较清楚的认识
好 那这个整个这个实验
我们说lab5的实验
我们最主要说要给应用程序
需要提供一个用户态的运行空间
那这个呢其实包含了两部分内容
一部分什么呢
一部分是内存管理
一个进程要运行
那必须要有个内存空间它所
运行所需要的代码段
数据段有内存空间
它有个内存空间的管理
和我们的lab2lab3有紧密的联系
第二个呢 进程管理
这也是我们这次实验的重点
但是我们已经有lab4
其实已经有一部分的进程管理
但是那时候我们叫内核线程
进程和线程的关系是什么呢
那么在原理课里面是讲过
大家想一想
进程和线程什么关系
那么这里面多了一点不同在哪呢
用户进程和内核线程
它们之间的关系和区别是什么
在这里面我们ucore操作系统呢
对这个用户进程和内核线程呢
有一套几乎统一一套管理体制
但是它们有很大的区别
那这里面我们希望通过完成
lab4和lab5呢对
这两者有更清楚的认识
对于内存管理而言
我们还需要知道
怎么去创建一个用户态的虚拟空间
我们之前的实验都是在内核里面
创建内核态的虚拟空间
那这里面不一样
我们要新增一个用户态虚拟空间
这需要去了解的
对于进程管理而言呢
我们需要知道怎么去加载
一个应用程序到
这个进程空间里面去
怎么去复制
怎么去创建新的子进程
就所谓的复制
我们叫fork
第三个呢 怎么去管理
整个进程的生命周期
第四个怎么让进程得到
操作系统服务
这是进程管理的功能
那么这一部分内容呢也是新的
那么也是在我们的lab5中
希望通过实现
实现相应的一些练习和阅读代码呢
能够对这些内容呢
有一个比较清楚的理解
那我们可以简单的看一下
怎么在lab5中构造出一个用户进程
它的流程大致这样的
首先我们要创建用户代码段
和用户的数据段
那么这对我们的lab几
大家想一想
对我们lab1中的
段机制的管理呢做了一个扩展
我们在lab1中
只讲到了内核的代码段和数据段
那这里面多了两个
用户的代码段和数据段
这里面有个扩充
有扩充之后呢
第二步呢我们能够创建内核线程
这一点是在lab4中完成了
创建内核线程的目的
是为进一步创建用户进程做好准备
所以说在这里面呢
我们首先要创建用户进程的壳
所谓创建它的壳呢就是说
要能够创建一个进程的控制块
以及进程控制块
所管理的很多关键的一些数据
比如说我举个简单例子
后面看到它的ID
它的执行状态等等
这后面会进一步展开
有了壳之后呢
我们需要具体的执行内容
这个内容从哪来呢
是我们应用程序里面
提供了它的具体执行
比如前面讲的hello world小程序
它有具体的执行内容
我们把这个内容呢
要放到这个进程里面去
比如说这个进程的代码段的空间里面
我们要把具体程序的内容放进去
从而可以使得它可以进一步执行
放进去之后呢
就可以执行这个用户进程了
但需要注意的是跟前面的不同在哪呢
这个执行是在用户空间执行的
不是在内核空间执行的
这是我们前面四个实验没有碰到
你怎么能够从内核态跳到用户态去
这涉及到特权级的一个转换
那在回顾一下
我们在前面实验中专门讲过
特权级它的特点是什么
它怎么去实现转换的
和我们中断管理机制有很紧密的联系
在执行应用程序过程中
它可能需要我们操作系统的服务
为此呢我们需要去
完成一个系统调用的一个管理机制
从而可以实现怎么去有效
我发这个请求
怎么能得到操作系统有效的服务
当用户进程执行完毕之后
那我们操作系统需要
把这个用户进程所占的资源
比如内存空间等等给回收回来
从而可以退出这个进程
那么我们就要有
结束用户进程管理体制
这里面就涉及到
进程的生命周期管理
从最开始创建到最后的结束
那么这就是整个我们说lab5里面
会碰到的一些实验的一个过程