L8 CPU管理的直观想法
CPU的工作原理——取址执行
将程序读入内存,设置PC初值,CPU将地址从地址总线发出,读取内存,再将指令从总线返回,CPU执行指令,PC增加,接着下一个循环...
存在的问题
如果程序中包含IO(如scanf),CPU需要等待IO结果才可以继续往下执行,这个时间CPU处于空闲,效率低。
注:IO操作不占用CPU时间
怎么解决——并发执行程序
多道程序、交替执行
在等待IO时CPU去执行别的指令
怎么实现?
除了修改PC,实现程序跳转,还需要记录程序(进程)的上下文信息的结构(PCB)。
这个上下文信息只有程序在运行时才会产生的。
进程——运行中的程序
L9多进程图像
用户视角:多个进程同时运行
CPU视角:将多个进程记录好、按照合理的次序推进(分配资源、进行调度)
多进程图像从操作系统启动到关机一直存在
操作系统初始化的最后一条语句是
if(!fork()){init();}
相当于创建一个进程,这个进程执行init();init()的作用是启动一个shell,等待用户的命令。
shell是以下程序
while(1){
scanf("%s",cmd);
if(!fork()){
exec(cmd);
}
wait();
}
用户在shell输入一个命令,shell会创建一个新进程,在该进程内完成任务
多进程如何组织?——PCB+状态+队列
PCB记录进程信息
操作系统维护多个PCB的队列
进程状态图
多进程如何交替?——队列操作+调度+切换
-
pCur.state=‘W’ 将进程状态设置为阻塞态
-
schedule() 负责切换进程
-
getNext(ReadyQueue) 从就绪队列里取一个进程,关于先取哪个进程涉及到“调度”后边会讲解。
-
pCur,pNew代表PCB
-
switch_to()涉及上下文切换
调度
- FIFO?priority?暂时不展开讲
切换
- 保存当前上下文,恢复新的上下文:利用PCB保存寄存器值
多进程之间会不会彼此影响?
存在的问题:多个进程的程序都在内存中,可能会使用相同的内存。
注意:
- 不能用DPL=0的方法限制访问,因为只有内核DPL=0,用户进程的DPL,CPL都为3
解决方法:
通过映射表实现多进程的地址空间分离(内存管理部分的内容)
同一个逻辑地址映射到不同物理地址。
因此说进程管理连带内存管理形成多进程图像
多进程如何合作?
例子:生产者-消费者实例
-
生产者进程、消费者进程、共享数据区
-
生产者进程:向共享数据区放
-
消费者进程:从共享数据区取
-
共享数据区:counter满了不能放,counter为0不能取
存在的问题:
将counter++;拆分成原子操作来看,发现问题。
解决方案——进程同步
上锁