0 回顾
操作系统合理的、交替的推进各个进程的指令往下执行 什么是多进程图像?就是有多个进程,比如这里就是
I
D
ID
I D 为1,2,3的这三个进程 从上层用户当中,怎么使用计算机呢?启动进程后,就开始使用计算机了 下层呢?操作系统负责记录好这3个进程,怎么记录呢?每个进程创建好一个PCB,创建好后,就记录好你这个进程怎么样了,到哪里了,所以底下的操作系统,合理有序的推进这多个进程 所以这就是多进程图像,用户只关注样子,操作系统关注多进程怎么推进 这个多进程图像一直存在于操作系统开机到关机的始终过程
这个任务管理器 本身也是一个进程,看这幅图就知道,计算机是多个进程在使用,如果慢了,可以看某个进程的CPU利用率,看看哪个进程导致他变慢
比如说
W
i
n
d
o
w
s
Windows
Win d o w s 当中的多进程就是如此
1.1 fork()
main初始化之后,执行了一堆init的函数之后,启动了一个进程,if (!fork()) {init();},fork()创建了第一个进程:shell,是初始化进程,shell再启动其他的进程,
W
i
n
d
o
w
s
Windows
Win d o w s 则是创建个图形交互界面,之后再执行其他进程。以下为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
2 总结