- 一个操作系统=内核+配套的应用程序
- 内核是操作系统最核心的内容
- 硬件的驱动程序都是在系统内核中执行的
- 进程是操作系统中涉及的关键性概念(与写代码密切相关)
01.什么是进程/任务 (Process/Task)
进程就是操作系统提供的一种"软件资源".
我们常用的操作系统,都属于"多任务操作系统"(即同一时刻,可以同时运行多个任务), 比如画图板,浏览器,QQ音乐,系统后台......,这些正在运行的程序,就可以称为"进程" / "任务"。(进程:跑起来的程序)
每个任务在执行的时候,都要消耗一定的硬件资源(CPU+内存+磁盘+网络)
计算机中的每个进程在运行时都需要给它分配一定的系统资源, 进程是系统分配资源的基本单位。
02. 操作系统的进程管理
2.1 管理的角度
1.描述
使用类/结构体,把被管理的一个对象,各个属性都表示出来。
2.组织
使用数据结构,把这些表示出来的对象,串起来。
系统中专门有一个结构体(操作系统内核是使用C/C++写的) 描述进程的属性,这个结构体统称为"进程控制块"PCB。
- 使用这个 PCB 描述进程的属性.
- 一个进程就可以使用一个或者多个 PCB 来表示
概念:使用类/结构体这样的方式,把实体属性列出来,表示进程的结构体,称为PCB(Process Control Block, 即进程控制块)
系统中会使用类似于双向链表这样的数据结构来组织多个 PCB
- 创建新的进程, 就是创建 PCB 并且把 PCB 插入到链表中
- 销毁进程,就是把 PCB 从链表上删除并释放展示进程列表,就相当于是遍历链表的每个节点~~
2.2 PCB的重要属性
PCB这个结构体,是一个具有上百个属性的结构体,非常庞大
1.pid:进程的身份标识(身份证号码)
每个进程都会有一个 pid,同一时刻,不同进程之间的 pid 是不同的
2.内存指针(一组属性)
描述了进程都能使用哪些内存.
每个进程在运行的时候,都会分配一定的内存空间,
这个进程,内存空间,具体是在哪里,以及分配的内存空间中有哪些部分, 每个部分都是干啥的....
有这么一组指针来进行区分.
最典型的,进程的内存空间,需要有专门的区域存储要执行的指令,以及指令依赖的数据
同时还需要存储一些运行时产生的临时数据
描述了进程持有的内存资源
3.文件描述符表
描述了进程所涉及的硬盘相关的资源,我们的进程经常要访问硬盘
类似于顺序表这样的数据结构,有很多元素
同时,PCB中引入了一些属性,用来支持操作系统实现进程调度的效果。
描述了进程持有的硬盘资源
以下描述了进程的调度效果(进程持有的CPU资源)
(进程的调度和进程的CPU资源,密切相关)->(进程太多,CPU核心数太少)
4.进程的状态
描述某个进程,是否能够去 cpu上执行.
- 就绪状态:进程时刻准备好,去 cpu 上执行.
就绪状态,具体有两种情况
1)进程正在 cpu 上执行.
2)虽然进程没在 cpu 上执行,但是时刻准备着去 cpu 执行- 阻塞状态:某个进程,某种执行条,件不具备,就导致这个进程暂时无法参与 cpu 的调度执行(比如,进程等待用户输入...)
5.进程的优先级
操作系统在调度多个进程的时候并非是一视同仁,有些进程会给更高的优先级,优先调度
我的电脑上同时运行 dota2(优先级更高) 和 qq(更低),
6.进程的上下文(存档、读档)
进程从 cpu 离开之前,需要保存现场,把当前 cpu 中各种寄存器的状态,都记录到内存中,等到下次进程回到 cpu 上执行的时候,此时就可以把保存的这些寄存器的值,恢复回去.进程就会沿着上次执行到的位置,继续往后执行。
CPU 中有些寄存器,属于没有特定含义,就只是用来保存运算的中间结果的还有些寄存器,是有特定含义,特定作用的.
1)保存当前执行到哪个指令 (程序计数器)
是一个 2 字节/ 4 字节 /8 字节 整数这个整数存的是一个 内存地址(程序下一条要执行的指令所在的位置)
2) 维护栈相关的寄存器通过这一组(一般是两个)维护当前程序的"调用栈"栈,也是一块内存,这个内存里就保存当前这个程序方法调用过程中,一系列的关系(也包含局部变量和方法参数....)
ebp 始终指向栈底
esp 始终指向栈顶.修改 esp 的值就可以实现"入栈"/"出栈
3)其他的通用寄存器了:往往是用来保存计算的中间结果的比如程序正在计算一个表达式
7.进程的记账信息
通过优先级机制,对不同的进程分配了不同权重的资源,有可能会出现极端的情况,所有的资源都给某个进程,其他进程一点都没捞着,这时候考虑给某些进程多分配些。
记账信息,会记录当前进程持有 cpu 的情况(在 cpu 执行多久了)就可以作为操作系统调度进程的参考依据
3.虚拟地址空间
早期的操作系统,程序运行时分配的内存,就是"物理内存"
此时存在一个问题:B 进程越界访问了 A 进程的内存,把 A 的内存写坏了(写成错误的值
了),A 进程就可能崩溃【不合理】
- 操作系统要给进程提供稳定的运行环境,
- 操作系统引入"虚拟地址空间"概念.不是直接分配物理内存了,而是分配虚拟的内存空间.
- 操作系统对于内存又进行了一层抽象.
A 操作某个内存中的数据就需要把操作的虚拟地址告诉系统系统再把虚拟地址翻译成物理地址(操作系统就可以进行检查/校验了.就需要看看当前这个虚拟地址是否能顺利完成翻译如果给定的虚拟地址是非法的,是一个越界的访问,系统就能及时发现,并且对当前进程进行处理,就不会波及到其他进程。)(有一个类似于hash 表这样的映射结构, 称为 页表)
再操作物理地址
以上就可以引入进程的独立性
通过上述方式,把进程之间给隔离开了,如果某个需求中,确实就需要让多个进程相互配合,此时就不好搞了此处就需要引入新的机制, 来实现进程之间的 通信
具体的实现方式有很多,但是每个方式的核心思想都是一样的.->都是要借助一个公共空间,完成数据的交互
两种方式:
1.通过文件
2.网络(socket)