操作系统 —— 进程线程模型
一、基础概念
进程的分类
系统进程,用户进程;前台进程,后台进程;CPU密集型进程,I/O密集型进程
进程层次结构
UNIX:进程家族树;Windows:地位相同
进程映像
对进程执行活动全过程的静态描述
上下文切换
将CPU硬件从一个进程换到另一个进程的过程称为上下文切换。进程不运行时,寄存器的值保存于PCB,要允许新进程时,PCB的相关值送到对应的寄存器。
进程控制块 PCB
PCB —— Process Control Block,又称进程描述符。
操作系统用于管理控制进程的一个专门数据结构。进程与PCB一一对应。
- 进程描述信息
- 进程标识符(process id),唯一,通常是一个整数
- 用户标识符(user id)
- 进程名
- 进程组关系
- 进程控制信息
- 当前状态
- 优先级
- 代码执行入口地址
- 程序的磁盘地址
- 运行统计信息
- 进程间同步和通信
- 进程的队列指针
- 进程的消息队列指针
- 所拥有的资源和使用情况
- 虚拟地址空间的状况
- 打开文件列表
- CPU现场信息
- 寄存器值
- 指向该进程页表的指针
二、进程的状态及状态转换
6种基础状态
- 运行态: 占有CPU,并在CPU上运行
- 就绪态: 已经具备运行条件,但无空闲CPU,而暂时不能运行
- 等待态: 也叫阻塞态、封锁态、睡眠态,因等待某一时间而暂时不能运行
- 创建: 已完成创建,但尚未同意执行该进程
- 终止: 终止进程,资源回收
- 挂起: 用于调节负载,其进程映像交换到磁盘上
进程队列:
伴随着进程的改变,其PCB从一个队列进入另一个队列
进程控制:
进程控制操作完成进程各状态之间的转换,由具有特定功能的原语
完成。
进程创建原语,进程撤销原语,阻塞原语,唤醒原语,挂起原语,激活原语,改变进程优先级。
原语(primitive)又叫原子操作(atomic)
- 完成特定功能的一段程序,具有不可分割或不可中断性
- 即原语的执行必须是连续的,在执行过程中不允许被中断
进程的执行过程
- 进程的创建
- 为新进程分配一个唯一标识以及PCB
- 为进程分配地址空间
- 初始化进程控制块
- 设置相应的队列指针
- UNIX: fork/exec; WINDOWS: CreateProcess
- exec: 通过用一段新的程序代码覆盖原来的地址空间,实现进程执行代码的转换
- 进程的撤销
- 结束进程
- 收回进程所占有的资源
- 关闭打开的文件、断开网路连接、回收分配的内存
- 撤销该进程的PCB
- UNIX: exit; WINDOWS: TerminateProcess
- 进程的阻塞
- 等待某一事件发生,在其尚未发生时,由进程自己执行阻塞原语,使自己由运行态变为阻塞态
- UNIX: wait; WINDOWS: WaitForSingleObject
Fork 的实现
实现原理
- 为子进程分配一个空闲的进程描述符(proc结构)
- 分配给子进程唯一标识pid
- 以一次一页的方式复制父进程地址空间(Linux采用了写时复制技术COW加快创建进程Copy-On—Write)
- 从父进程处继承共享资源,如打开的文件和当前工作目录等
- 将子进程的状态设为就绪,插入到就绪队列
- 对子进程返回标识符0
- 向父进程返回子进程的pid
三、线程的引入
概念
为什么在进程中再派生出线程?
- 应用的考虑
- 开销的考虑
- 性能的考虑
线程:进程中的一个运行实体,是CPU的调度单位,有时将线程称为轻量级进程
- 有标识符ID
- 有状态及状态转换 -> 需要提供一些操作
- 不运行时需要保存上下文
- 有自己的栈和栈指针
- 共享所在进程的地址空间和其他资源
- 可以创建、撤销另一个线程
线程机制的实现
用户级线程,核心(Kernel)级线程,混合-两者结合方法。
用户级线程小结
- 优点:
- 线程切换快
- 调度算法是应用程序特定的
- 用户级线程可运行在任何OS上
- 缺点:
- 内核只能讲CPU分配给进程,同一进程中的两个线程不能同时运行于两个处理器上
- 大多数系统调用是阻塞的,因此由于内核阻塞进程,进程中的所有线程也被阻塞
- 可以将系统调用改为非阻塞的
- Jackeing/Wrapper
- 如果进程内一个线程被阻塞,那么整个进程就会被阻塞,无法充分利用多处理器的优势;而如果一个线程异常,那么整个进程也就完蛋了