0 回顾
- 操作系统合理的、交替的推进各个进程的指令往下执行
- 什么是多进程图像?就是有多个进程,比如这里就是 I D ID ID为1,2,3的这三个进程
- 从上层用户当中,怎么使用计算机呢?启动进程后,就开始使用计算机了
- 下层呢?操作系统负责记录好这3个进程,怎么记录呢?每个进程创建好一个PCB,创建好后,就记录好你这个进程怎么样了,到哪里了,所以底下的操作系统,合理有序的推进这多个进程
- 所以这就是多进程图像,用户只关注样子,操作系统关注多进程怎么推进
- 这个多进程图像一直存在于操作系统开机到关机的始终过程
这个任务管理器本身也是一个进程,看这幅图就知道,计算机是多个进程在使用,如果慢了,可以看某个进程的CPU利用率,看看哪个进程导致他变慢
- 比如说 W i n d o w s Windows Windows当中的多进程就是如此
1 多进程图像
1.1 fork()
main初始化之后,执行了一堆init的函数之后,启动了一个进程,if (!fork()) {init();}
,fork()创建了第一个进程:shell,是初始化进程,shell再启动其他的进程,
W
i
n
d
o
w
s
Windows
Windows则是创建个图形交互界面,之后再执行其他进程。以下为shell进程的代码:
int main(int argc,char argv[])
{
while(1)
{
scanf("%s", cmd);
if(!fork())
{
exec(cmd);
}
wait();
}
}
用户执行一个任务,也是创建一个进程,这个进程完成你要完成的任务。
- 执行任务->创建进程->任务结束
- 通过多进程图像,就能看到计算机是怎样跑的
- 启动一个进程就开始使用计算机了
- 所以说多进程图像是计算机核心的图像
- 所以说用户启动计算机就是启动了一堆进程,用户管理计算机就是管理一堆进程
1.2 组织多进程
- 操作系统感知进程,全靠PCB,组织进程也是全靠PCB,用PCB形成一些数据结构,所以说计算机组织好多进程才能管理好多进程,就是用PCB这个结构体形成一堆数据结构,就出现了队列这个数据结构。
- 就绪队列:有多个进程,有一个进程正在执行,为什么是一个呢?因为是单核的CPU(或者多核的,但是进程太多了总得有就绪队列)
- 等待队列:缺事件的进程,即使排到了也得继续等待事件
- 把进程根据状态进行区分
- 以上为进程状态图
- 所以这就是个操作系统对进程的组织,也是对进程的一系列管理
- 要求会画这个图
- 要求会讲解这个图
- 运行→等待;运行→就绪;就绪→运行,其实有没有发现,这是一个进程不断向前推进的图,而操作系统就在这个状态基础上对进程进行控制和管理
- 总结,如何组织多进程?
- 用PCB放在不同的队列中,用状态来推进这多个进程,进行状态转化,这就是操作系统进行多进程的组织过程
1.3 多进程的交替
- 所谓多进程的交替,就是不断的切换,这是最核心的东西
- 如果不能这样交替切换,多进程就没有意义了,就变成单道批处理了
- 下图中的schedule(),getNext函数是重点,即切换和调度
- 下图中的getNext从就绪队列中挑出下一个占用CPU的进程
- switch_to就是用PCB进行进程上下文的切换,pCur、pNew分别指当前进程的PCB和调度得到的下一个进程的PCB,因为操作系统都是根据PCB来感知一个进程
- 找哪个进程合适?根据getNext来找
- 选好了就完成具体的切换,因为PCB都保存了当时的信息(现场信息),所以能进行切换
1.4 交替的三个部分
-
队列操作+调度+切换
-
一些基本的调度了解一下
- 调度就是进程的切换,你已经找到了下一个进程了,就要切换下一个进程
- 怎么切换呢?首先会把当时的信息记录下来,到PCB当中保存现场,将当前CPU的各种信息(寄存器等)保存到pCur中,将pNew中的寄存器等信息恢复到CPU中
- 伪代码:
- 总结前文
- 第一,操作系统如何组织进程,即根据进程的状态,用进程的PCB形成各种队列
- 第二,操作系统如何完成进程调度与切换,即schedule()找到下一个进程(调度);CPU信息保存到PCBcur,.PCBnew的信息恢复到CPU(切换)
- 引出下文
- 第三,多个进程交替执行会相互影响,包括正面的多进程合作,负面的内存地址冲突等等
1.5 互斥
- 多个进程同时存在会相互影响,例如会发生内存地址的冲突
- 之前讲了操作系统和用户进程需要隔离,现在引出新的问题,用户进程之间的内存也需要隔离
- 一个进程原则上不能随意访问另一个进程的内存
- 多进程的地址空间分离:内存管理的主要内容,也就是说,多进程图像需要完成对内存的管理
- 如下图的代码,两个进程在同一个100内存地址发生了冲突
- 解决方法:内存映射
- 两个进程的100内存地址,是虚拟内存地址,会映射到不同的物理内存
- 下图中展示了两个进程的100地址分别映射到了物理地址780和1260
- 多进程,都在内存当中,是操作系统内存管理的核心
- 以上就是虚拟内存技术
1.6 合作
- 多个进程如果不做处理,就会乱套
- 顺序执行就不会乱,但是这是交替执行,当进程1还没放完的时候,进程2就要放进去了
- 合作实例:根据共享数据进行合作
- 对共享数据的操作会引发问题
- 例如counter如果不加以保护,其最终结果很可能不符合预期
- 生产者进程的counter++和消费者进程的counter- -分别对应3条指令,如下图中间所示
- 下图右侧展示了一种可能的引发错误的指令执行序列,因为多进程放在内存当中交替执行的,预期结果是5,实际结果是4,所以合作就乱套了
- 所以多进程合作,需要注意共享数据的正确性,核心在于进程同步
- 例如在一个进程写counter时,需要阻断其他进程访问counter
- 下图展示了一种锁机制,用于保护共享数据counter