进程控制的主要功能是对系统中的所有进程实施有效的管理,它具有创建新进程、撤销已有进程、实现进程状态转换等功能。
简化理解:进程控制是要实现进程状态转换。
进程控制相关的原语
- 启动(创建进程):创建态 -> 就绪态
- 被 CPU 调度、切换:就绪态 -> 运行态
- 进程执行时系统调用等待某个事件的请求:运行态 -> 阻塞态
- 等待资源修改,分配资源:阻塞态 -> 就绪态
- 终止进程,回收资源:运行态 -> 终止态
进程控制用原语实现
为什么要使用原语?
避免没有及时修改 PCB 中的信息,因为不及时修改会很危险。
用 原语 实现进程控制。原语的特点是执行期间 不允许中断,只能一气呵成。
这种不可被中断的操作即 原子操作。
参考资料:
原语采用 “关中断指令” 和 “开中断指令” 实现。(特权指令)
进程控制会导致进程状态的转换。
- 更新 PCB 中的信息(如修改进程状态标志、将运行环境保存到 PCB、从 PCB 恢复运行环境)
- 所有的进程控制原语一定都会修改进程状态标志
- 剥夺当前运行进程的 CPU 使用权必然需要保存其运行环境
- 某进程开始运行前必然要恢复期运行环境
- 将 PCB 插入合适的队列
- 分配/回收资源
进程创建原语
允许一个进程创建另一个进程。此时创建者称为父进程,被创建的进程称为子进程。子进程可以继承父进程所拥有的资源。当子进程被撤销时,应将其从父进程那里获得的资源归还给父进程。此外,在撤销父进程时,也必须同时撤销其所有的子进程。
无 -> 创建态 -> 就绪态
操作系统创建新进程的过程:
- 为新进程分配一个唯一的进程标识号,并申请一个空白的 PCB(PCB 是有限的)。若 PCB 申请失败则创建失败
- 为进程分配资源,为新进程的程序和数据、以及用户栈分配必要的内存空间(在 PCB 中体现)。注意:这里如果资源不足(比如内存空间),并不是创建失败,而是处于“等待状态”、或称为“阻塞状态”,等待的是内存这个资源。
- 初始化 PCB,主要包括初始化标志信息、初始化处理机状态信息和初始化处理机控制信息,以及设置进程的优先级等。
- 如果进程就绪队列能够接纳新进程,就将新进程插入到就绪队列,等待被调度运行
进程终止原语
引起进程终止的事件主要有:
- 正常结束:表示进程的任务已经完成和准备退出运行;
- 异常结束:指进程在运行时,发生了某种异常事件,使程序无法继续运行,如存储区越界、保护错、非法指令、特权指令错、I/O故障等;
- 外界干预:指进程应外界的请求而终止运行,如操作员或操作系统干预、父进程请求和父进程终止。
操作系统终止进程的过程如下(撤销原语):
- 根据被终止进程的标识符,检索PCB,从中读出该进程的状态。
- 若被终止进程处于执行状态,立即终止该进程的执行,将处理机资源分配给其他进程。
- 若该进程还有子进程,则应将其所有子进程终止。
- 将该进程所拥有的全部资源,或归还给其父进程或归还给操作系统。
- 将该 PCB 从所在队列(链表)中删除。
就绪态/阻塞态/运行态 -> 终止态 -> 无
进程阻塞和唤醒原语
正在执行的进程,由于期待的某些事件未发生,如请求系统资源失败、等待某种操作的完成、新数据尚未到达或无新工作做等,则由系统自动执行阻塞原语(Block),使自己由运行状态变为阻塞状态。可见,进程的阻塞是进程自身的一种主动行为,也因此只有处于运行态的进程(获得 CPU),才可能将其转为阻塞状态。
阻塞原语的执行过程是:
- 找到将要被阻塞进程的标识号对应的 PCB。
- 若该进程为运行状态,则保护其现场,将其状态转为阻塞状态,停止运行。
- 把该PCB插入到相应事件的等待队列中去。
唤醒原语的执行过程是:
- 在该事件的等待队列中找到相应进程的 PCB。
- 将其从等待队列中移出,并置其状态为就绪状态。
- 把该 PCB 插入就绪队列中,等待调度程序调度。
阻塞原语(Block)和唤醒原语(Wakeup)必须成对使用。Block 原语是由被阻塞进程自我调用实现的,而 Wakeup 原语则是由一个与被唤醒进程相合作或被其他相关的进程调用实现的。
进程的切换
对于通常的进程,其创建、撤销以及要求由系统设备完成的 I/O 操作都是利用系统调用而进入内核,再由内核中相应处理程序予以完成的。进程切换同样是在内核的支持下实现的,因此可以说,任何进程都是在操作系统内核的支持下运行的,是与内核紧密相关的。
进程切换是指处理机从一个进程的运行转到另一个进程上运行,这个过程中,进程的运行环境产生了实质性的变化。
进程切换的过程如下:
- 保存处理机上下文,包括程序计数器和其他寄存器。
- 更新 PCB 信息。
- 把进程的 PCB 移入相应的队列,如就绪、在某事件阻塞等队列。
- 选择另一个进程执行,并更新其PCB。
- 更新内存管理的数据结构。
- 恢复处理机上下文。