Skip to content

设备分配与回收

2026 大纲 五(二)2 设备分配与回收,属「设备独立软件」层。

两个进程同时要打印机,给谁

应用程序接口说应用只报逻辑设备名、由系统映射到物理设备。 这一节讲映射那一步真正要做的事——当有多个进程同时要设备时,怎么分。

分设备比分内存麻烦,因为设备不是一个孤立的东西。 在有通道的系统里,一次 I/O 要打通的是一整条链路:

进程通道控制器设备

三级中任何一级忙着,这次 I/O 就走不通。 所以分配不是"找一台空闲设备"那么简单, 而是要沿这条链路逐级确认——这就是四张表(SDT → DCT → COCT → CHCT)存在的理由, 它们沿物理链路逐级向下指,每级各带忙/闲标志与等待队列。

要考虑的东西也不止"有没有空"。 至少三样: 设备的固有属性(独占还是共享,决定能不能同时给多个进程)、 设备的当前状态(忙还是闲)、 逻辑名到物理设备的映射(应用报的是逻辑名,得先落到具体某台)。 另外权限也要查——不是谁都能动任意一台设备。

最后是分配策略的取舍。安全分配摒弃了"请求和保持"(申请到一台就阻塞、 不会攥着一台再要另一台),因而不会死锁,代价是 CPU 与 I/O 完全串行; 不安全分配推进快,但每次都得做安全性计算。这一对取舍与 死锁那一章是同一套判据的两次出现。

一、设备分配中的数据结构

一次数据传输走的是这样一条物理链路

内存通道控制器设备

数据结构正是照着这条链路建的,指针方向与链路方向一致:

数据结构有几张关键字段指针指向谁、为什么
SDT(系统设备表)全系统 1设备类型、设备标识符、DCT 指针驱动程序入口它是唯一的入口,必须能从"设备名"找到那台设备的详细信息;顺带存驱动入口,省得再查一次
DCT(设备控制表)每台设备 1 张设备类型 type、设备标识 deviceid、忙/闲标志设备队列队首指针指向 COCT 的指针重复执行次数设备忙时要把请求进程的 PCB 排成队列,队首指针就是为此;设备必须知道自己挂在哪个控制器下才能继续往下查
COCT(控制器控制表)每个控制器 1 张控制器标识、忙/闲标志、等待队列指针指向 CHCT 的指针同理,控制器要知道自己挂在哪个通道下
CHCT(通道控制表)每个通道 1 张通道标识、忙/闲标志、等待队列指针通道是链路末端(对内存侧),不再往下指

DCT 里的重复执行次数来自另一条需求:外设传数据容易出错,系统规定出错时可重复执行若干次,只有达到规定次数仍不成功才算失败——这是差错控制在数据结构上的落点。

二、设备分配时要考虑的三件事

考虑维度取值与策略
① 设备的固有属性独占设备:分配给某进程后由它独占,直到进程完成或主动释放;共享设备:可同时分配给多个进程,但要合理调度访问次序;虚拟设备:属可共享设备,可同时分配给多个进程(由 SPOOLing 实现)
② 设备分配算法先来先服务:按请求先后排成设备请求队列,总是分配给队首进程;优先级高者优先:高优先级排队列前面,同优先级按先来先服务
③ 分配中的安全性安全分配:发出 I/O 请求后立即阻塞,I/O 完成才唤醒 → 不会死锁,但 CPU 与 I/O 串行;不安全分配:发出请求后继续运行,仅当所请求设备已被占用时才阻塞 → 可同时操作多台设备、推进快,但可能死锁

三、设备分配的完整步骤

以进程用物理设备名提出请求为例:

  1. 分配设备:按物理设备名查 SDT → 找到该设备的 DCT → 看忙/闲标志。忙 → 把请求进程的 PCB 挂到该设备的等待队列;闲 → 做安全性计算,安全才分配,不安全仍插入等待队列。
  2. 分配控制器:从 DCT 找到与该设备相连的 COCT → 看忙/闲标志。忙 → 把 PCB 挂到该控制器的等待队列;闲 → 分配。
  3. 分配通道:从 COCT 找到 CHCT → 看忙/闲标志。忙 → 把 PCB 挂到该通道的等待队列;闲 → 分配。
  4. 只有设备、控制器、通道三者都分配成功,本次分配才算成功,随即启动设备开始传输。

改用逻辑设备名请求后,系统从 SDT 中找该类设备的第一台,忙就找第二台、第三台……仅当该类设备全部被占用时进程才挂到该类设备的等待队列上。这是"设备独立性"在分配环节的收益。

四、设备的回收

分配的镜像操作。进程用完设备(或进程终止)时,系统沿链路逐级释放

步骤动作唤醒谁
释放设备把该设备 DCT 的忙/闲标志置为"闲",清除与该进程的占用关系若 DCT 的设备等待队列非空,唤醒队首进程,把设备分配给它
释放控制器把 COCT 的忙/闲标志置"闲"若 COCT 等待队列非空,唤醒队首进程
释放通道把 CHCT 的忙/闲标志置"闲"若 CHCT 等待队列非空,唤醒队首进程
注销登记项若是用逻辑设备名请求的,撤销 LUT 中的对应表项——

五、设备独立性与逻辑设备表 LUT

用户程序用逻辑设备名请求设备(如 /dev/printer,只说明"我要打印机",不指定哪一台),系统用逻辑设备表 LUT 把它映射到物理设备,表项含逻辑设备名、物理设备名、驱动程序入口地址(存入口地址是为省去再查 SDT 的一次间接)。

进程首次用逻辑名请求时,系统分配一台物理设备并在 LUT 中建立表项;以后再用同一逻辑名发起 I/O,查 LUT 就能直接找到物理设备与驱动入口。

六、引入 SPOOLing 之后,分配的是什么

独占设备分配有个绕不开的问题:打印机一次只能给一个进程用,别人只能排队干等SPOOLing 改变的正是"分配的对象":

没有 SPOOLing有 SPOOLing
进程申请到的是打印机本身(一台物理独占设备)输出井中的一块空闲盘块 + 一张打印请求表
什么时候能继续跑打印完数据写进输出井就返回
会不会因它死锁会(可能与别的独占设备形成循环等待)不会
分配的本质分配一台设备分配一块磁盘空间(可共享资源)

这就是"虚拟设备"能被同时分配给多个进程的原因——被分配的其实是磁盘上的空间,而磁盘是共享设备

考点速记

  1. 四张表 SDT → DCT → COCT → CHCT 沿物理链路逐级向下指(系统设备表 → 设备控制表 → 控制器控制表 → 通道控制表),三级各带忙/闲标志与等待队列。⚠️通道、控制器、设备三者都空闲才分配成功;回收时逐级释放并唤醒各级队首。
  2. 设备分配要考虑四件事设备的类型(独占/共享/虚拟,决定能不能同时给多个进程)、设备的访问权限设备的占用状态(忙/闲)、逻辑设备与物理设备的映射关系。⚠️ 四条都要考虑,一条都不多余。
  3. 分配的完整步骤:查 SDT 找设备类 → 查 DCT 看设备忙不忙 → 查 COCT 看控制器忙不忙 → 查 CHCT 看通道忙不忙 → 三级都通才建立链路。任何一级忙就把进程挂到该级的等待队列。
  4. 安全分配摒弃了"请求和保持"——申请到一台设备就阻塞自己,不会攥着一台再去要另一台,因而不会死锁,代价是 CPU 与 I/O 完全串行
  5. 不安全分配允许进程持有设备的同时继续申请,推进快,但必须每次做安全性计算
  6. 用逻辑设备名请求 + LUT 映射是设备独立性的落点:同类设备有一台空闲就不阻塞,换设备不改程序,还顺带支撑 I/O 重定向。
  7. 引入 SPOOLing 之后,分配给进程的是"虚拟设备"(井中的一块空间 + 一条请求记录),真正的物理设备由系统独家管着。

这一节在真题里被考过的形式

只出过一道题,问的是"设备分配要考虑哪些因素",四条全对。

  • 问设备分配需要考虑哪些因素(2023-32)。答设备的类型 + 设备的访问权限 + 设备的占用状态 + 逻辑设备与物理设备的映射关系四条全部。⚠️ 这道题的设计意图是别把设备分配想窄了——它不只是"找一台空闲的"(占用状态),还要看这台设备是独占还是共享(类型,决定能不能同时给多个进程)、这个进程有没有权限动它(权限)、以及应用报的逻辑名该落到哪一台(映射)。四个维度各回答一个不同问题,与设备的基本概念那四套分类标准是同一个思路。

复习优先级必须拿满,但内容不多。 速记第二条那四条就是唯一一道题的答案。 第一条那四张表的名字与顺序要能默写(它们沿物理链路排,不是随便列的), 第四、五条那对取舍与死锁章共用判据, 在那边还会再用一次。

易错:认为设备分配只需看设备忙不忙。还要看类型、权限、逻辑到物理的映射,四条都要考虑。

易错:只查设备空不空就建立链路。通道、控制器、设备三级都空闲才行,任何一级忙都得排队。

易错:把四张表的顺序记乱。它们沿物理链路逐级向下:系统设备表 → 设备控制表 → 控制器控制表 → 通道控制表。

易错:认为安全分配也可能死锁。它摒弃了"请求和保持"——申请到一台就阻塞,攥不住第二台。

教材出处
  • 设备控制表 DCT 的字段(设备队列队首指针、忙/闲标志、控制器表指针、重复执行次数)与 COCT、CHCT、SDT 三表:汤小丹《计算机操作系统》6.5.3 节,印刷 p201–202
  • 设备分配的三个考虑因素、安全分配"摒弃了造成死锁的四个必要条件之一的请求和保持条件"、独占设备分配程序的三步与改用逻辑设备名的改进:同书 6.5.3 节,印刷 p202–203
  • 逻辑设备表 LUT 的三项表项内容:同书 6.5.4 节,印刷 p203
  • 引入 SPOOLing 后"实际上并没为任何进程分配设备,而只是在磁盘缓冲区中为进程分配一个空闲盘块和建立一张 I/O 请求表":同书 6.6.2 节,印刷 p207

相关知识

设备的基本概念与分类缓冲区管理死锁的概念与必要条件假脱机技术(SPOOLing)

真题练习