第二章 进程管理
进程的描述
进程 是操作系统中 最核心 的概念。
程序的顺序执行与程序的并发执行
程序的顺序执行
先进入内存的程序先执行,在一个程序执行完毕之前,不能执行其他程序。
顺序执行的 特点:
- 顺序性:前一操作结束后,才能执行后续操作;
- 封闭性:运行时独占全机资源,各资源的状态只有本程序才能改变;
- 可再现性:程序多次执行,执行结果相同;
顺序执行的 问题:输入/输出设备、CPU 不能同时忙碌。
程序的并发执行
指在 同一时间间隔内 运行多个程序。一个程序执行结束前,可以运行其他程序。
并发执行的 特点:
- 间断性:程序在CPU上执行时,是时续时断的;
- 失去封闭性:系统的状态不再只对正在执行的程序可见;
- 不可再现性:同一个程序在输入相同的情况下多次运行,可能出现不同的结果;
进程的概念
进程的定义
允许 并发执行的程序 在某个 数据集合 上的 运行过程。
进程的 结构:
- 用户正文段:存放被执行的机器指令;
- 用户数据段:存放进程在执行时直接进行操作的用户数据;
- 进程控制块(PCB):存放程序的 运行环境,进程实体的标志;
进程的特征
- 并发性:多个进程实体能 在一段时间间隔内同时运行,进程和现代系统的重要特征;
- 动态性:进程是实体的 执行过程;
- 独立性:独立运行和资源调度的 基本单位;(没有线程的情况下)
- 异步性:进程的执行时续时断,何时执行、何时暂停(随时可以被终止)都 无法预知;
- 结构特征:用户正文段、用户数据段、进程控制块;
进程和程序的比较
进程和程序的 区别:
进程 | 程序 |
---|---|
动态 | 静态 |
暂时保存 | 永久保存 |
程序的运行过程 | 指令的集合 |
进程和程序的 联系:
- 进程 是 程序 的一次执行;
- 一个 程序 可以对应多个 进程;(相加的程序,1+1=2、2+2=4)
- 同一个 进程 能够顺序地执行几个 程序;(财务系统包含多个模块 - 计算模块、存储模块)
进程控制块
进程控制块是 进程实体的一部分,是操作系统中 最重要的数据结构。
进程控制块中记录了 操作系统 所需要的、用于 描述进程及控制进程运行 所需的全部信息。包括:
- 进程标识符信息:用于唯一标识一个进程;
-
处理机状态信息:
- 通用寄存器;
- 指令计数器;
- 程序状态字PSW;
- 用户栈指针;
-
进程调度信息:
- 进程状态信息;
- 进程优先级;
- 进程调用所需的其他信息;
-
进程控制信息:
- 程序和数据的地址;
- 进程同步;
- 通信机制;
- 资源清单;
- 链接指针;
进程的状态
- 就绪态;
- 执行态;
- 阻塞态:又叫等待态和封锁态;
进程的组织
- 链接方式:把具有相同状态的进程控制块用其中的 链接字 连成一个队列;
- 索引方式:系统根据所有进程的状态,建立 索引表,索引表的每一个 表项 都指向一个进程控制块;
- 进程队列:把具有相同状态的进程控制块用 队列 组织起来;
在大部分时刻,都会有一个进程处于 CPU 中,否则可能是全部的进程都处于异常状态(死锁)。
进程的控制
进程的控制指:创建 - 阻塞 - 唤醒 - 终止。
进程的创建
进程创建的 时机:用户登录、作业调度、提供服务、应用请求。
创建进程的 过程:
- 申请 空白的进程控制块;
- 为新进程 分配资源;
- 初始化 进程控制块;
- 将新进程 插入到就绪队列;
当新进程被创建时,有两种 执行可能:
- 父进程和子进程 并发执行;
- 父进程 等待,直到某个或全部子进程执行完毕;
进程的阻塞
进程阻塞的 时机:请求系统服务、启动某种操作、新数据尚未到达、无新工作可做。
阻塞进程的 过程:
- 将进程的状态 改为阻塞态;
- 将进程 插入相应的阻塞队列;
- 转到进程调度程序,从就绪队列中选择进程为其分配CPU;
进程的唤醒
唤醒进程的 过程:
- 将进程 从阻塞队列中移出;
- 将进程状态由阻塞状态 改为就绪态;
- 将进程 插入就绪队列;
进程的终止
终止进程的 时机:进程正常执行完毕。
终止进程的 过程:
- 从进程控制块中 读取进程状态;
- 若进程正在执行,则终止进程的执行;
- 释放资源;
- 将终止进程的 进程控制块移出;
操作系统内核
操作系统内核是计算机硬件的第一次扩充,内核执行操作系统与硬件关系密切、执行频率高的模块,常驻内存。
操作系统内核的 功能:
- 支撑功能:中断处理、时钟管理、原语操作;
- 资源管理功能:进程管理、存储管理、设备管理;
中断
中断是 改变处理器执行指令顺序 的一种事件。
出现中断时,计算机 停止现在程序的进行,转向 对这些中断事件的处理,处理结束后再 返回到现行程序的间断处。
引入中断前,CPU通过 反复轮询 的方式,检测本次 I/O 是否结束。
引入中断机制后,CPU可以与其他设备 并行工作,能有效 提高CPU的利用率、改善系统性能、支持系统的异步操作。
开中断 是响应中断的前提。
中断的 分类:
- 同步中断(内部中断、异常);
- 异步中断(外部中断):外部可屏蔽中断、外部不可屏蔽中断;
在 Inter 微处理器手册 中,把同步中断和异步中断称为 异常 和 中断。
中断的 原因:
- 人为设置中断;
- 程序性事故;
- 硬件故障;
- I/O设备;
- 外部事件;
中断的 处理:
时钟管理
时钟是计算机系统的脉搏,计算机的许多活动都是由 定时测量 来驱动的。
系统可以利用 时钟机制 限制一个用户进程在CPU连续执行的时间。
操作系统中的 时钟:
- RTC实时时钟:CMOS,类似于:秒表、初始时间;
- OS时钟:由 操作系统 控制,类似于:系统时间;
操作系统的 时钟机制:时钟硬件、时钟驱动程序。
每产生一次时钟中断信号,操作系统都要执行时钟驱动程序。
操作系统内核需要完成的两种定时测量是:维持定时器、保存当前的日期和时间。
OS时钟管理硬件:可编程间隔定时器 PIT。
时钟驱动程序的 功能:
- 维持 日期和时间;
- 递减当前 进程 在一个时间片内的剩余执行时间,防止运行超时;
- 对 CPU 的使用情况记账;
- 递减 报警计数器;
系统调用
系统调用是一群 预先定义好的模块。
提供 一条管道 让 应用程序 能由此到 核心程序 的服务。
系统调用是 系统程序 与 用户程序 之间的 接口。
用户空间:用户进程 所处的地址空间。
用户态执行:CPU 执行用户空间的代码 时,称该进程处于用户态执行。
系统空间:含有一切 系统核心代码 的地址空间。
系统态执行:CPU 执行系统空间的代码 时,称该进程处于系统态执行。
系统调用和一般函数调用之间的 区别:
- 系统调用运行在 系统态(管态),一般函数调用运行在 用户态(目态);
- 执行过程 不同;(系统调用执行时,当前进程被中断)
- 系统调用进行 中断处理,多了系统开销;
系统调用的 类型:
- 进程 控制类;
- 文件 操纵类;
- 设备 管理类;
- 通信 类;
- 信息 维护类;
进程同步
进程同步的基本概念
进程同步:进程并发执行,共享系统的资源,操作系统对共享过程进行控制和管理。
同步机制:保证在 多任务共享系统资源 的情况下,程序执行能得到正确的结果。
多道程序环境下进程之间的关系:(进程同步的任务)
- 资源共享关系:保证各进程以 互斥 的方式访问 临界资源;(有两个进程需要使用同个资源(打印机、CPU)时,一个进程的使用需要等待另外一个进程结束使用)
- 相互合作关系:保证相互合作的各进程 协调 执行;(存在两个进程,一个进程依赖另一个进程的结果集,需要保证进程的执行顺序)
临界资源:必须 以互斥方式访问 的共享资源。
临界区:进程中 访问临界资源 的那段 代码。
同步机制应遵循的准则
- 空闲让进:没有进程处于临界区,应允许一个请求进入临界区的进程进入;
- 忙则等待:临界区已有进程,其他试图进入临界区的进程必须等待;
- 有限等待:对于要访问临界资源的进程,应保证有限时间内进入临界区;
- 让权等待:申请不到访问权,应释放处理机,以免浪费CPU资源;
信号量机制
用 信号量的取值 来表示资源的使用状况,以此为基础实现进程同步。
信号量:某种类型的变量,如:整型、记录型。
根据 信号量类型 的不同,可以分为:
- 整型信号量机制;
- 记录型信号量机制;
- AND型信号量机制:所有资源 一次性地全部 分配给进程;
整型信号量机制
整型信号量是 表示共享资源状态 且只能由特殊的 原子操作 改变的 整型量。
原子操作:wait
、signal
。
原理:定义一个用于 互斥 的整型信号量,用该变量的值来 标记资源的使用情况。
整型信号量 > 0:有资源可用。
整型信号量 <= 0:资源忙,需等待。
对应 原子操作 的实现:
Var s integer;
wait(s)
{
while s<=0 do no-op; // 整型信号量值 <= 0 时,循环执行空操作;
s = s - 1;
}
signal(s)
{
s = s + 1;
}
用整型信号量实现 进程互斥:
为互斥访问的临界资源CS定义一个 互斥信号量mutex,将初始值置为 1。将临界资源CS放入 wait(mutex) 和 signal(mutex) 之间。
wait(mutex);
CS
signal(mutex);
用整型信号量实现 进程协调:
存在p1和p2两个进程,为互斥访问的临界资源CS定义一个 互斥信号量s,将初始值置为 0。
parbegin
begin p1; signal(s); end
begin wait(s); p2; end
parend
记录型信号量机制
原理:定义一个 记录型变量,用该变量的值来 标记资源的使用情况。
// 记录型信号量的数据类型
Type semaphore = record
value: integer; // 资源数量
L: list of process; // 阻塞队列
end
s.value >= 0 时,s.value
的值表示 资源数量。
s.value < 0 时,s.value
的 绝对值 表示等待队列中 阻塞进程的数量。
对应 原子操作 的实现:
Var s semaphore;
wait(s)
{
s.value = s.value - 1;
if s.value < 0 then block(s.L)
}
signal(s)
{
s.value = s.value + 1;
if s.value <= 0 then wakeup(s.L)
}
用记录型信号量实现 进程互斥:
用记录型信号量实现 进程协调:
进程通信
- 共享存储器系统:相互通信的进程共享某些数据结构或共享存储区;
- 共享数据结构:生产者-消费者问题中,使用界缓冲区;
- 共享存储区;
- 消息传递系统:进程间通过操作系统提供的一组通信程序传递消息;
- 直接通信方式:利用发送程序直接发送消息;
- 间接通信方式:需要通过 数据结构 来实现,例如:邮箱;
- 管道通信:进程间通过管道(链接读写进程的特殊文件)进行信息通道;
- 管道文件存在于 外存 中;
- 消息缓冲队列:
- 广泛用于 本地进程 之间的通信;
- 利用 数据结构、发送原语和接收原语 实现信息通信;
- 消息缓冲区:进程标识符、消息长度、消息正文、指向下一个消息缓冲区的指针;
高级通信机制:共享存储器系统、消息传递系统、管道通信
线程
线程的概念
线程是进程中的一个实体,是被系统 独立调度和分派 的 基本单位。
线程只能拥有在运行中必须的资源,包括 程序计数器、一组寄存器和栈,但它可与同一进程的其他线程 共享进程所拥有的全部资源。
线程间通过直接 读/写全局变量 来进行通信。
线程控制 是线程实现中最基本的功能。
线程的分类
- 内核级线程:依赖于内核;
- 用户级线程:不依赖内核;
内核线程 | 用户线程 | |
---|---|---|
内核 | 内核维护上下文信息,以 线程 为单位进行调度 | 以 进程 为单位进行调度 |
调度 | 可分配多个CPU,支持 并行 | 采用 非抢占式 |
切换 | 需要 用户模式和内核模式的切换 | 不需要 用户模式和内核模式的切换 |
线程的基本状态
- 运行态;
- 就绪态;
- 阻塞态;
线程控制块
每一个线程都由一个 数据结构 表示,包括它的基本状态等,这个数据结构就是 线程控制块TCB。包括:
- 线程标识符信息;
- 处理机状态信息;
- 线程调度信息;
- 线程控制信息;
线程控制块通常采用 链接 方式来组织。
TCB记录了操作系统需要的、用于 描述线程情况及控制线程运行 所需的全部信息。
线程和进程的区别
- 线程 是 程序执行 的基本单位,进程 是 拥有资源 的基本单位;
- 不同进程的地址空间是相互独立的,而 同一进程中的各线程共享同一个地址空间;
- 进程之间的通信必须使用操作系统提供的进程间通信机制,而 同一进程中的各线程间可以直接通信;
- 多进程之间可以并发执行,多线程之间也可以并发执行;
- 线程切换的开销 比进程切换的开销 小;