操作系统笔记-2.1.4 进程控制
·
王道操作系统笔记,视频链接:2.1.4 进程控制
定义:进程控制的主要功能是对系统中的所有进程实施有效的管理,它具有创建新进程、撤销已有进程、实现进程状态转换等功能。
简化理解:反正进程控制就是要实现进程状态转换
如何实现进程控制

- 进程的控制需要用“原语”实现。
复习:原语是一种特殊的程序,它的执行具有原子性,其运行必须一气呵成,不可中断。 - 问:为什么进程控制(状态转换)的过程要“一气呵成”?
示例如图:
如果不一气呵成,中断信号就可能导致某些关键的数据结构(如PCB)信息不统一的情况,这就可能影响操作系统,让后续运行出错。
如何实现原语的“原子性”
- 原语的执行具有原子性,即执行过程只能一气呵成,期间不允许被中断。
- 可以用“关中断指令”和“开中断指令”这两个特权指令实现原子性。
- 关中断和开中断指令都是特权指令,其作用顾名思义是开启和关闭中断信号的检查。中断信号的检查阶段发生在每条指令执行之后,所以利用开中断和关中断指令将原语包括起来,那么就可以实现原子性,如图:

- 关中断和开中断指令都是特权指令,其作用顾名思义是开启和关闭中断信号的检查。中断信号的检查阶段发生在每条指令执行之后,所以利用开中断和关中断指令将原语包括起来,那么就可以实现原子性,如图:
- 如果这两个特权指令允许用户程序使用,那么用户程序就可以实现全称霸占CPU,拒绝交出权限。
进程控制相关的原语
创建原语
- 定义:操作系统创建一个进程时使用的原语称为创建原语。
- 申请空白PCB
- 为新进程分配所需资源(内存空间等)
- 初始化PCB(分配PID,设置UID等)
- 将PCB插入就绪队列(创建态->就绪态)
- 引起进程创建的事件:
- 用户登录:分时系统中,用户登录成功,系统会为其建立一个新的进程
比如用户管理进程、用户通讯进程等。 - 作业调度:多道批处理系统中,有新的作业放入内存时,会为其建立一个新的进程
作业就是放在外存里,还没有投入运行的程序。作业调度就是从外存中挑选一个程序放入内存运行。 - 提供服务:用户向操作系统提出某些请求时,会新建一个进程处理该请求
- 应用请求:由用户进程主动请求创建一个子进程
撤销原语
- 定义:要终止一个进程时使用的原语。(就绪态/阻塞态/运行态->终止态->无)
- 从PCB集合中找到终止进程的PCB
- 若进程正在运行,立即剥夺CPU,将CPU分配给其他进程
- 终止其所有子进程
比如:祖先进程kernel_task的PID为0,创建了一个它的子进程launchd(也称装入程序或者叫装入进程,后面第三章会讲),其PID为1。
在开机后我们启动的所有其它进程都是依靠装入进程启动的,所以其它进程都是装入进程的子进程。
当然,其它父进程也能有自己的子进程,父进程可以按照子进程的需要将手里的资源分配给子进程,子进程结束后,掌握的资源也得返还给父进程。
进程间的关系是树形结构,不过这不是操作系统这门课考察的重点,了解即可。 - 将该进程拥有的所有资源归还给父进程或操作系统
- 删除PCB
- 引起进程终止的事件:
- 正常结束:比如进程自己请求终止(exit系统调用)
- 异常结束:比如整数除以0,非法使用特权指令,然后被操作系统强行杀掉
- 外界干扰:ctrl+alt+delete,用户选择杀掉进程
阻塞原语
PS:这些原语并不需要死记硬背,考试不会考默写,所以理解它背后的过程即可。
- 定义:进程需要从运行态转换到阻塞态,就需要阻塞原语。
- 找到要阻塞的进程对应的PCB
- 保护进程运行现场,将PCB状态信息设置为“阻塞态”,暂时停止进程运行
- 将PCB插入相应事件的等待队列
- 引起进程阻塞的事件:
- 需要等待系统分配某种资源
- 需要等待相互合作的其他进程完成工作
唤醒原语
- 定义:进程需要从阻塞态转换到就绪态,就需要唤醒原语。
- 在事件等待队列中找到对应的PCB
- 将PCB从等待队列移除,设置进程为就绪态
- 将PCB插入就绪队列,等待被调度
- 引起进程唤醒的事件:
- 等待的事件发生
- 注意,一个进程因何事阻塞,就应由何事唤醒。
- 注意2,阻塞原语与唤醒原语必须成对使用。
切换原语
- 定义:切换原语会让此时正在处于运行态的进程下处理机,让它回到就绪队列,并且从就绪队列当中选择一个就绪态的进程上处理机运行。
- 将运行环境信息(进程上下问,context)存入PCB
- PCB移入相应队列
- 选择另一个进程执行,并更新其PCB
- 根据PCB恢复新进程所需的运行环境
- 引起进程切换的事件:
- 当前进程时间片到
- 有更高优先级的进程到达
- 当前进程主动阻塞
- 当前进程终止
关于运行环境
这部分涉及到计组内容,用于辅助理解“存储运行环境”和“恢复运行环境”在做什么。
- CPU在执行运行的时候会设置很多“寄存器”,用来存放程序运行过程中所需的某些数据。
比如:
- PSW(程序状态字寄存器),CPU的状态就是存储在这里的。
- PC(程序计数器),存放下一条指令的地址。
- IR(指令寄存器),存放当前正在执行的指令。
- 通用寄存器,用于存放别的信息
举例:
四条指令: - 指令1:往内存中某个地方写入变量x的值(比如x初始化为1)
- 指令2:把变量x的值放到某个寄存器中
- 指令3:寄存器中的数值+1
- 指令4:把寄存器的值写回变量x的存放位置
- 这几条指令完成的是定义x变量,然后完成x++操作
运行步骤: - 当运行指令1时,指令1的内容会被读入IR,下一条指令的地址,也就是指令2的地址就会被放入PC。
- 指令1执行完后,CPU会从PC中得知下一条指令,指令2内容读入IR,指令3的地址被读入PC。指令2要求将x的值放在某个寄存器中,所以某个通用寄存器中将会储存这个值(也就是1)。
- 指令2执行完成后,同理,指令3内容读入IR,指令4地址读入PC,指令3要求寄存器中的数值+1,所以通用寄存器中的数值变为1+1=2
- 指令3执行完成后,IR读入指令4,PC读入指令5地址,指令4将寄存器的值写回内存中,所以此时内存中的x的值变为2。
PS:如果x是全局变量或者静态变量,那么这里的x实际存储在进程实例的数据段中。 - 注意,微观上,在当前时间片,进程确实是占有这些寄存器的,但是宏观上寄存器是公共资源,需要多个进程使用,如果不进行存储这个环境的步骤,一个进程计算出来的寄存器上的中间值就可能会被其它进程修改。
所以为了解决这个问题,在进程切换时,先在PCB中保存这个进程的运行环境(也就是保存一些必要的寄存器信息,比如PSW、PC、以及所有的通用寄存器,因为CPU不确定哪些通用寄存器被使用了,所以必须全部保存)。当原来的进程再次投入运行时,可以通过PCB恢复它的运行环境。
PS:在考研基础层面,通常默认讨论整数运算相关的核心寄存器组;浮点寄存器、向量寄存器等属于扩展状态,在基础考纲中通常忽略或由硬件惰性处理,不在本问题考察范围内。
知识回顾与重要考点
如图所示:
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)