设备分配与回收

这一节回答:进程说”我要用打印机”,系统凭什么、按什么步骤把设备交给它。

本节的四张控制表是全章公认最难记的部分。难记的原因是它们通常被当成四组字段来背——但它们其实是一条指针链,而这条链的形状完全由一个事实决定:一次 I/O 需要设备、控制器、通道三样同时到位,缺一不可。 抓住这一点,四张表的存在理由、字段构成和分配步骤全都能推出来。

机制

设备分配要考虑什么

① 设备的固有属性。 独占设备、共享设备、虚拟设备三类,分配策略完全不同:独占设备只能整台给一个进程,共享设备可以多个进程交替使用,虚拟设备则由 SPOOLing 造出来。

② 设备分配算法。 常用先来先服务和优先级高者优先,与进程调度算法同源。

③ 设备分配的安全性。 即这样分会不会导致死锁。

疑问点:不属于设备分配考虑因素的选项

  1. 在下列问题中,( )不是设备分配中应考虑的问题。 A. 及时性 B. 设备的固有属性 C. 设备独立性 D. 安全性

答案 A。 这道题的四个选项看起来”都挺像”,判据在于它们是不是设备分配这一步要做的决定:

B 固有属性决定了能不能独占——是分配前必须先判断的事。D 安全性决定了这样分会不会死锁——是分配时必须评估的事。C 设备独立性决定了逻辑名映射到哪台物理设备——正是分配要选出那一台(见 5.2.1)。

A 及时性关心的是”I/O 请求能不能在规定时间内被响应”,这是实时系统的调度指标或 I/O 性能指标,与”把哪台设备交给谁”这个决定无关。

安全分配方式与不安全分配方式

这一组是按”进程提出 I/O 请求后还能不能继续跑”来划分的:

安全分配方式——进程发出 I/O 请求后立即进入阻塞态,直到 I/O 完成才被唤醒。因此一个时段内每个进程最多只占用一台设备。

优点是不会死锁:进程在等待 I/O 时不再申请新设备,破坏了”请求和保持”条件。缺点是 CPU 与 I/O 设备串行工作,进程推进慢。

不安全分配方式——进程发出 I/O 请求后仍继续运行,还可以接着发出第二个、第三个请求,只有当它请求的设备已被别人占用时才阻塞。

优点是一个进程可以同时操作多个设备,推进迅速;缺点是可能死锁——它恰好满足了”请求和保持”。

名字里的”安全”指的就是”不会死锁”,与数据是否安全无关。

静态分配与动态分配

这一组是按”什么时候分”来划分的:

静态分配——在进程运行前一次性分配它所需的全部设备、控制器和通道,一旦分配就一直归它使用,直到进程撤销才释放。

它同样破坏了”请求和保持”条件,因而不会死锁,但设备利用率极低——一台设备可能整个进程生命周期里只用了几秒钟,却被独占到最后。

动态分配——进程运行过程中按需分配,用完立即释放。利用率高,但可能死锁。

规律是一致的:凡是”提前一次性拿够”的方案都不会死锁,代价都是利用率低。 这与 2.4.2 死锁预防中破坏”请求和保持”条件的做法是同一件事。

四张控制表:为什么是四张

疑问点:设备控制表的结构难以理解与记忆

设备控制表的内容较复杂,难以理解,也记不住。

先解决”为什么要有这些表”,字段就不用背了。

关键事实只有一条:一次 I/O 要走完 “通道 → 控制器 → 设备”这条完整路径,因此必须三样同时空闲,只要有一样被占用,这次 I/O 就走不通。

既然三样都是可能被占用的资源,就三样都要有一张表来记录”我忙不忙、谁在等我”。 于是有了 DCT(设备)、COCT(控制器)、CHCT(通道) 三张表;再加上一张 SDT(系统设备表) 作为总目录,用来从设备名找到对应的 DCT。

graph TD
    SDT["<b>SDT 系统设备表</b><br/>全系统唯一 · 总目录<br/><i>记录所有设备,指向各自的 DCT</i>"]
    DCT["<b>DCT 设备控制表</b><br/>每台设备一张<br/>① 我是谁:设备类型 / 标识符<br/>② 我忙不忙:设备状态<br/>③ 谁在等我:设备队列队首指针<br/>④ 我接在谁身上:→ COCT 指针"]
    COCT["<b>COCT 控制器控制表</b><br/>每个控制器一张<br/>状态 · 等待队列 · <b>→ CHCT 指针</b>"]
    CHCT["<b>CHCT 通道控制表</b><br/>每个通道一张<br/>状态 · 等待队列"]
    SDT -->|按设备名查到| DCT
    DCT -->|沿指针向上| COCT
    COCT -->|沿指针向上| CHCT
    classDef top fill:#fef3c7,stroke:#d97706,color:#78350f
    classDef mid fill:#dbeafe,stroke:#2563eb,color:#1e3a8a
    classDef bot fill:#dcfce7,stroke:#16a34a,color:#14532d
    class SDT top
    class DCT mid
    class COCT,CHCT bot

DCT 不需要背字段,它只回答四个问题:

① 我是谁(设备类型、设备标识符) ② 我忙不忙(设备状态:忙 / 闲) ③ 谁在等我(设备队列的队首指针) ④ 我接在谁身上(指向控制器控制表的指针)

COCT 和 CHCT 的结构与 DCT 完全同构,也是”我忙不忙 + 谁在等我 + 我接在谁身上”,只是最后一项 CHCT 没有(通道已经是最上面一级,再往上就是 CPU 了)。

所以四张表真正需要记的只有两件事:

第一,每张表都记”状态 + 等待队列”——因为它们都是可能被抢占的资源。

第二,每张表都有一个”向上的指针”——因为分配了设备还不够,必须顺着指针把它所连的控制器和通道一并拿到手。这条指针链就是分配步骤的路线图。

设备分配的步骤

有了那条指针链,分配步骤就是照着它走一遍:

① 根据物理设备名查 SDT,找到该设备的 DCT。

② 查 DCT 的状态。 若设备忙,把进程 PCB 挂到该设备的等待队列上;若空闲,把设备分配给进程。

③ 沿 DCT 中的指针找到 COCT,查控制器状态。 忙则挂到控制器的等待队列,空闲则分配。

④ 沿 COCT 中的指针找到 CHCT,查通道状态。 忙则挂到通道的等待队列,空闲则分配。

⑤ 设备、控制器、通道三者都分配到手,才能启动 I/O。

回收时反向进行:释放通道、控制器、设备,并唤醒各自等待队列上的进程。

一句话记法:从 SDT 找设备,查 DCT 分设备,沿指针查 COCT 分控制器,再沿指针查 CHCT 分通道;有一样忙,就挂到那一样的等待队列上。

边界

为什么必须三样都分配到才能启动

这是四张表存在的全部理由,也是最容易被忽略的一点。

数据要从设备走到内存,必须经过控制器和通道——这条路径上任何一段被别人占用,数据就过不来。所以哪怕设备本身是空闲的,只要它所连的控制器正忙着为另一台设备服务,这次 I/O 也启动不了。

这也解释了为什么等待队列有三个而不是一个:进程可能卡在三个不同的地方,系统必须知道它到底在等什么,才能在对应资源释放时唤醒正确的进程。

独占设备与共享设备的分配方式

疑问点:独占设备与共享设备的说法辨析

  1. 下面关于独占设备和共享设备的说法中,不正确的是( )。 A. 打印机、扫描仪等属于独占设备 B. 对独占设备往往采用静态分配方式 C. 共享设备是指一个作业尚未撤离,另一个作业即可使用,但每个时刻只有一个作业使用 D. 对共享设备往往采用静态分配方式

答案 D。

A 对:打印机、扫描仪一旦被一个作业用上,中途插进另一个作业就会把输出搅乱,因此必须独占。

B 对:独占设备正因为不能中途易主,才适合静态分配——运行前一次性给足,用到进程结束。这样虽然利用率低,但避免了死锁,对这类设备是合算的。

C 对:这正是”宏观上同时、微观上交替”的准确表述,与 5.1.1 那道题的结论一致。

D 错:共享设备恰恰应该采用动态分配。 共享设备(如磁盘)本来就允许多个进程交替使用,若也搞静态分配、让一个进程从头独占到尾,共享就无从谈起了。

判据可以概括为:不能中途易主的用静态分配,能中途易主的用动态分配。

“安全分配”与”静态分配”不是同一组概念

两者都能避免死锁,容易被当成一回事,但切分角度不同:

安全 / 不安全问的是”进程提出 I/O 请求后还能不能继续运行”。

静态 / 动态问的是”设备是运行前一次性分完,还是运行中按需分配”。

它们避免死锁的机制其实相同——都是破坏”请求和保持”条件,但破坏的方式不同:安全分配方式让进程”在等 I/O 时不再提新请求”;静态分配让进程”一开始就把所有要的都拿齐,之后不再提请求”。

同一台机器上两组概念可以自由组合,它们不是同义词。

设备分配与进程调度的相似性

四张表的分配逻辑与进程调度高度相似:都是”查资源状态 → 空闲则分配、忙则排队 → 释放时唤醒队首”。

差别在于设备分配要一次拿齐三样资源,而这正是死锁的温床——一个进程拿到了设备在等控制器,另一个进程拿到了控制器在等设备,就是典型的循环等待。

理解这一点,就能明白为什么设备分配这一节要专门讨论”安全性”,而进程调度那一节不必。

对照速查

设备分配要考虑的三项
①设备的固有属性(独占 / 共享 / 虚拟)
②设备分配算法(FCFS、优先级)
③设备分配的安全性(会不会死锁)
不考虑及时性(那是实时调度或性能指标)
安全分配方式不安全分配方式
提出请求后立即阻塞继续运行,可再提请求
同时用几台设备一台多台
会死锁吗不会(破坏请求和保持)可能
代价CPU 与 I/O 串行—
静态分配动态分配
何时分运行前一次性分完运行中按需分
何时还进程撤销时用完立即释放
会死锁吗不会可能
利用率低高
适用独占设备共享设备
四张表数量记什么
SDT 系统设备表全系统一张所有设备,指向各自的 DCT
DCT 设备控制表每台设备一张我是谁 / 我忙不忙 / 谁在等我 / → COCT
COCT 控制器控制表每个控制器一张状态 / 等待队列 / → CHCT
CHCT 通道控制表每个通道一张状态 / 等待队列
分配步骤查哪张表
① 按设备名找到设备SDT
② 分配设备DCT(忙则挂设备等待队列)
③ 分配控制器COCT(忙则挂控制器等待队列)
④ 分配通道CHCT(忙则挂通道等待队列)
⑤ 三者齐备才能启动 I/O

考点

  • 设备分配考虑固有属性、分配算法、安全性;“及时性”不是
  • 安全分配方式 = 请求后立即阻塞 = 不会死锁但 CPU 与 I/O 串行
  • 静态分配适合独占设备,动态分配适合共享设备(真题选项 D 的错处)
  • 四张表的共同结构:状态 + 等待队列 + 向上的指针
  • DCT 四问:我是谁 / 我忙不忙 / 谁在等我 / 我接在谁身上
  • 分配顺序 SDT → DCT → COCT → CHCT,三者齐备才能启动
  • 三个等待队列的存在理由:进程可能卡在三个不同的地方

链接