第二章:进程的描述与控制

一、进程与线程

1. 进程的概念和特征

(1)进程的概念

  • 进程是程序的一次执行过程(进程与程序的关系)
  • 进程实体由程序段、相关数据段和PCB(进程控制块)构成
  • 创建和删除进程的本质是创建和删除PCB
  • PCB是进程存在的唯一标志

(2)进程的特征

  • 动态性
  • 并发性
  • 独立性
  • 异步性

其中,动态性是进程最基本的特性

2. 进程的状态与转换

进程状态描述
创建状态分配进程标识符并申请PCB—-分配资源—-初始化PCB—-插入就绪队列
就绪状态已分配到除CPU外的所有必要资源
执行状态单CPU中同一时刻只能有一个进程在执行
阻塞状态等待某一事件(通常是等待输入输出完成,比如等待打印机空闲)
终止状态操作系统善后处理—-PCB清零并返还系统
挂起操作为了系统和用户观察分析进程。

在操作系统中,挂起原语(Suspend)和激活原语(Activate)与挂起状态(Suspended State)的关系是管理进程生命周期的一部分。

挂起原语(Suspend): 挂起原语是操作系统中用于将进程从运行状态或就绪状态转换到挂起状态的一个系统调用或操作。当一个进程被挂起时,它通常会释放所占用的资源,并且其状态会被设置为挂起状态。挂起状态意味着进程不会被操作系统调度执行,直到它被激活或者被终止。

激活原语(Activate): 激活原语与挂起原语相反,它用于将处于挂起状态的进程恢复到就绪状态。当进程被激活时,它的状态会被设置为就绪,这意味着它可以被操作系统调度执行,只要它满足执行条件(如没有更高的优先级进程正在执行)。

挂起状态(Suspended State): 挂起状态是进程可以进入的一种状态,当进程被挂起原语操作时,它就会进入这种状态。在挂起状态下,进程不会消耗CPU资源,也不会执行任何操作,直到它被激活。挂起状态通常用于暂停进程以便进行维护、调试或等待某些事件(如等待I/O操作完成)。

总结来说,挂起原语和激活原语是操作系统用来控制进程状态转换的工具,而挂起状态则是进程在这些转换中可能经历的一种状态。通过这些操作,操作系统能够灵活地管理进程,以满足用户和系统的需求。

3. 进程的组织

(1)进程控制块(PCB)

(2)程序段

  • 能被进程调度到CPU执行的程序代码段(多个进程可以运行同一个程序)

(3)数据段

  • 程序加工处理的原始数据或程序执行时产生的中间结果或最终结果

4. 进程控制

(1)进程的创建

①父子进程

  • 父子进程之间代码共享,数据独有
  • 关系
    • 一个进程创建另一个进程,创建者称为父进程,被创建者称为子进程
    • 撤销子进程时,资源要归还父进程;撤销父进程时,要同时撤销所有子进程
    • 子进程可以继承父进程所有资源
    • 父子进程可以共享一部分资源,子进程创建也会分配自己独有的资源(2020)
    • 父子进程不能共享虚拟地址空间(2020)

②引起进程创建的事件

  • 用户登录、作业调度、系统提供提供服务、应用请求、启动程序执行(设备分配不会引起进程创建)(2010)

③进程创建过程

  • 分配进程标识符并申请PCB–>分配资源–>初始化PCB–>插入就绪队列(2021)

(2)进程的终止

引起进程终止的事件:

  • 正常结束:进程的任务已经完成并准备退出运行
  • 异常结束:存储区越界、保护错、非法指令、特权指令错、运行超时、算术运算错、I/O故障等
  • 外部干预:操作员或操作系统干预、父进程请求、父进程终止

(3)进程的阻塞和唤醒

  • BLOCK原语是自我调用(自己阻塞自己),Wake up原语是被其它进程调用(其它进程唤醒)

5. 进程的通信

进程间的低级通信方式为PV操作,后面会细讲,这里先详细介绍一下高级通信方式

(1)共享存储

  • 进程空间是独立的,一般不能被互相直接访问,所以需要一块共享空间作为中介
  • 进程对共享空间的访问必须是互斥的
  • 两个不同进程不能通过全局变量通信,全局变量是对同一进程而言的
  • 分类
    • 低级方式:基于共享数据结构
    • 高级方式:基于共享存储区

(2)消息传递系统

  • 将数据封装在消息中,使用发送和接收原语在进程间传递消息从而完成数据交换

分类:

通信方式描述
直接通信方式使用OS提供的发送原语直接将消息发送给目标进程
间接通信方式通过共享中间实体(邮箱),需要发送和接收原语

(3)管道通信系统

6. 线程和多线程模型

(1)线程的基本概念

  • 引入进程是为了多道程序并发执行;引入线程是未了减小程序切换的开销
  • 线程组成:线程ID、程序计数器、寄存器集合、堆栈
  • 同一进程中的线程切换不会引起进程切换;不同进程中的线程切换会引起进程切换
  • 线程不拥有系统资源(仅有一点必不可少的资源)
  • 同一进程的不同线程
    • 线程共享资源:地址空间(拥有相同的地址空间)、全局变量、打开的文件、子进程(2012)
    • 线程独享资源:程序计数器、寄存器、栈、状态字(2011)

(2)线程与进程的比较

(3)线程的状态与转换

  • 执行态、就绪态、阻塞态(类比线程)

(4)线程的实现方式

①用户级线程

  • 有关线程管理(创建、撤销和切换等)的所有工作都在用户空间完成
  • 内核意识不到线程的存在,处理及调度仍以进程为单位
  • 内核每次分配给一个进程一个CPU,因此进程中仅有一个线程能执行
  • 可以在不支持线程的操作系统上实现(2019)

②内核级线程

  • 有关线程管理的所有工作都在内核空间实现(2019)
  • 处理机调度以线程为单位
  • 内核能同时调度统一进程中的多个线程并行执行
  • 内核级线程比用户级线程的切换效率低(2019)

③组合方式

(5)多线程模型

模型描述
多对一模型一个进程的多个用户级线程映射到一个内核级线程上。
一个线程访问内核时阻塞则整个进程都被阻塞;任何时候只有一个线程能够访问内核
一对一模型每个用户级线程都有一个内核级线程与之对应。
一个线程被阻塞后,允许另一个线程运行,但开销较大
多对多模型用户级线程与内核级线程之间存在多对多的映射关系。
开销不大且并发性较高

二、处理机调度

1. 调度的概念

2. 调度的目标

性能指标描述
CPU利用率CPU在单位时间内用于处理作业的比率
系统吞吐量单位时间内CPU完成作业的数量
周转时间作业完成时间 - 作业提交时间
平均周转时间n个作业的周转时间平均值
带权周转时间作业周转时间/作业运行时间
平均带权周转时间n个带权周转时间的平均值
等待时间进程处于等待处理机的时间
响应时间用户提交请求到系统首次产生响应所需要的时间

3. 调度的实现

(1)调度时机

不能进行进程调度与切换的情况

情况描述
处理中断时中断处理复杂很难同时进行进程切换
进程在操作系统内核临界区中2012年真题指出进程在临界区时可以调度
其它需要完全屏蔽中断的原子操作中加锁、解锁、中断现场保护、恢复

(2)进程调度方式

  • 非抢占调度(非剥夺)
    • 不能用于分时系统和大多数实时系统
  • 抢占式调度(剥夺)

(3)闲逛进程

  • 进程切换时若没有其它进程就绪就执行闲逛进程
  • 闲逛进程的优先级最低,只要有进程就绪就会立即让出处理机
  • 闲逛进程不需要CPU之外的资源,因此不会被阻塞

4. 典型的调度算法

(1)先来先服务(FCFS)调度算法

  • 对长作业有利;对短作业不利
  • 有利于CPU繁忙型作业(一般是长作业);不利于I/O繁忙型作业(一般是短作业)

(2)短作业优先(SJF)调度算法

  • 对长作业不利;对短作业有利
  • 分为抢占式短作业优先和非抢占式式短作业优先(都会造成饥饿现象)(2011、2014)
  • 平均等待时间、平均周转时间最少

(3)优先级调度算法

调度相关特性描述
是否可以抢占剥夺式、非剥夺式
优先级是否改变静态优先级、动态优先级
进程优先级设置原则系统进程>用户进程;交互式进程>非交互式进程;I/O型进程>计算型进程(2013)

(4)高响应比优先调度算法

  • 综合考虑了每个进程的等待时间和执行时间(2009)

(5)时间片轮转调度算法

  • 主要适用于分时系统
  • 时钟中断发生后,系统会修改当前进程在时间片内的剩余时间(2017)
  • 时间片太大将退化为先来先服务调度算法;时间片太小处理机频繁进行进程切换则开销增大(2017)

(6)多级反馈队列调度算法(2019、2020)

  • 步骤
    • 设置多个队列,并为每个序列设置不同的优先级
    • 优先级越高的队列中时间片就越小,每个队列都采用FCFS算法
    • 进程进入内存后,先放入第1级队列的队尾,若未执行完,放入下一队列末尾
    • 只有当前面的队列执行完,才能执行后面的队列
    • 若有更高优先级的队列进入,当前进程放置所处队列的队尾,执行新来的进程
  • 特点
    • 对很多作业都能较好处理;可能造成饥饿

5. 进程切换

(1)基本概念

  • 上下文:某一时刻CPU寄存器和程序计数器的内容
  • 上下文切换:CPU从一个进程切换到另一个进程保存当前进程状态并回复另一个进程状态的过程
  • 进程切换要在内核支持下完成

(2)上下文切换流程

  • 挂起一个进程,保存其CPU上下文,更新其PCB并移入相应的队列
  • 选择新的进程,更新其PCB并转到程序计数器所指位置执行,恢复该进程的CPU上下文

(3)区分

操作系统概念解释
模式切换用户态和内核态之间的切换
调度决定资源分配给哪一个进程(一般现有资源调度后有进程切换)
上下文切换CPU从一个进程切换到另一个进程,保存当前进程的状态,并恢复另一个进程的状态的过程

三、同步与互斥

1. 同步与互斥的基本概念

(1)基本概念

概念解释
临界资源一次只允许一个进程使用的共享资源(打印机、共享变量、共享缓冲区、公用队列)
临界区每个进程中访问临界资源的代码段
临界资源访问过程进入区–>临界区–>退出区–>剩余区

(2)直接相互制约(同步)

  • 进程为完成同一项任务而协调工作次序所产生的制约关系

(3)间接相互制约(互斥)

  • 对临界资源只能互斥地访问

互斥机制应遵循的规则:

规则描述
空闲让进临界区空闲时,允许进程进入
忙则等待已有进程进入临界区时,其他进程必须等待
有限等待请求进入临界区的进程应在有限时间内进入
让权等待当进程不能进入临界区时,应立即释放处理器(不是必须遵守的规则)

2. 实现临界区互斥的基本方法

(1)软件实现

(2)硬件实现

中断屏蔽方法: 进程在执行临界区代码时,通过关中断防止其它进程进入临界区

3. 互斥锁

  • 进程在进入临界区时获得锁,在退出临界区时释放锁
  • 函数acquire()获得锁,函数release()释放锁,两者执行必须是原子操作。因此互斥锁通常采用硬件机制实现
  • 主要缺点:忙等待

4. 信号量

(1)特点

  • 是低级进程通信,因为效率低、对用户不透明
  • PV操作是原子操作不可被中断;PV操作不是系统调用
  • V操作能让进程进入就绪状态;P操作能让进程进入阻塞状态
  • value为正表示还有同类资源;value为-m表示有m个进程处于阻塞态等待使用资源(2010)
  • P(S)和wait(S)等价;V(S)和signal(S)等价(2022)

(2)分类

信号量类型描述
整型信号量wait(S): while(S<=0); S=S-1(这里可能卡在while语句一直循环占用处理器,故不遵循让权等待)
记录型信号量增加一个进程链表指针list,用于链接所有等待该信号量的进程。在wait操作后,进程会添加到链表中等待,实现了让权等待。(2018)

(3)应用

同步/互斥类型描述
进程同步使用信号量实现,确保X在Y之前执行。初值S为资源数量。
S=0; X;V;P;Y
进程互斥使用信号量实现,确保同一时刻只有一个进程能够进入临界区。
S=1; P1(P;临界区;V);P2(P;临界区;V)
实现前驱关系

5. 管程机制

(1)组成

  • 管程的名称
  • 局部于管程内部的共享数据结构说明
  • 对该数据结构进行操作的一组过程(或函数)
  • 对局部于管程内部的共享数据设置初始值的语句

(2)特点

  • 由编译语言支持的进程同步机制(2016)
  • 管程可以用于实现进程的同步或互斥(2016)
  • 所有进程都只能用过管程访问临界资源,管程每次只允许一个进程进入(2016)

(3)条件变量

  • 一种抽象数据类型,保存一个链表,用于记录因该条件变量而阻塞的所有进程
  • x.wait:把进程挂在x对应的阻塞队列上;x.signal:唤醒x的阻塞队列上的一个进程(2018)
  • 若没有等待进程,x.signal不会有任何操作,这与信号量中的signal不同(会修改信号量变量的值)

6. 经典同步问题

  • 大题部分细讲

四、死锁

1. 死锁的定义

两个或两个以上进程因竞争资源而相互等待,若无外力作用这些进程都无法向前推进(2019)

2. 死锁产生的原因

(1)系统资源的竞争

  • 竞争不可抢占性资源(磁带、打印机)

(2)进程推进顺序非法

问题描述描述
竞争可消耗资源信号量引起死锁
进程推进顺序不当1. 请求和释放资源的顺序不当(A申请B占有的资源,B申请A占有的资源)
2. 信号量使用不当(A等待B发消息,B等待A发消息)

3. 产生死锁的必要条件

死锁条件描述
互斥条件进程对资源只能互斥访问(一段时间内只能有一个进程访问)
不可抢占条件进程所获得的资源在未使用完毕前不可被其他进程剥夺。
请求和保持条件进程保持了至少一个资源的同时请求其他资源。
循环等待条件形成循环等待链,每个进程已获得的资源同时被下一个进程所请求。

4. 死锁的处理策略

(1)预防死锁

死锁条件破坏策略
破坏互斥条件将临界资源改为可共享资源(SPOOLing技术)
破坏不可抢占进程提出资源请求不能得到满足时释放自己已保持的全部资源
破坏请求和保持进程在开始之前,必须一次性申请所需全部资源
进程运行过程中逐步释放自己用过的资源再请求新资源
破坏循环等待对系统所有资源线性排序,进程必须按顺序请求资源

(2)避免死锁

原理

  • 在资源动态分配过程中,防止系统进入不安全状态

银行家算法

  • 可以求出安全队列;需要知道进程所需全部资源数
  • 银行家算法只能避免死锁,不能检测死锁(2013、2019)
  • n个进程,每个进程所需设备为x1,x2…xn,则保证不发生死锁的最小设备数为(x1-1)+(x2-1)+…(xn-1)+1(经常考)

不安全状态与死锁

  • 死锁一定是不安全状态;不安全状态不一定是死锁(2013)

(3)检测死锁

  • 资源分配图(有向图)
    • (学会简化资源分配图)
  • 死锁定理:S为死锁状态的充分条件是:当且仅当S的资源分配图是不可完全简化的

(4)解除死锁

方法描述
资源剥夺法抢占某些死锁进程的资源分配给其它死锁进程(2019)
撤销进程法撤销部分或全部死锁进程并剥夺这些进程的资源
进程回退法让进程逐个回退到足以回避死锁的地步