程序查询方式
三种 I/O 方式里最简单的一种,也是唯一一种 CPU 全程被占住的。
它的全部内容就是一个循环:读状态端口 → 没好就再读一遍 → 好了就传一个字 → 回去接着读。硬件上不需要任何额外机构——7.2.2 那张图里,只用到状态端口、数据端口、控制端口三个,INTR 和 MASK 两个触发器完全用不上。
正因为简单,它的考点集中在代价上:CPU 到底浪费了多少,以及”忙等”在 OS 眼里是什么状态。
机制
流程
flowchart TD S["CPU 向控制端口<br/>写启动命令"] --> W["设置传送计数<br/>与主存缓冲区首址"] W --> R["读状态端口"] R --> Q{"D = 1?<br/>(设备就绪)"} Q -->|"否"| R Q -->|"是"| T["读数据端口<br/>→ CPU 寄存器"] T --> M["CPU 寄存器<br/>→ 主存"] M --> C["地址 +1,计数 −1"] C --> E{"传完了?"} E -->|"否"| R E -->|"是"| F["结束"] classDef loop fill:#ffcdd2,stroke:#b71c1c,stroke-width:3px classDef norm fill:#e3f2fd,stroke:#1565c0 classDef done fill:#c8e6c9,stroke:#1b5e20 class R,Q loop class S,W,T,M,C,E norm class F done
红色的那两个框就是”忙等”——CPU 在这里空转,执行的是有效指令(读状态、比较、转移),但不产生任何有用的工作。
图上还有一处值得注意:数据走了两步。 设备 → 数据端口 → CPU 寄存器 → 主存。中间必须经过 CPU 寄存器,这一点与程序中断方式相同,与 DMA 不同——这正是 7.1.3 对照表里”数据流路径”那一行的来源。
独占查询与定时查询
教材把查询方式再分两种,区别在于”查完没好之后干什么”。
| 独占查询 | 定时查询(周期性查询) | |
|---|---|---|
| 没就绪时 | 原地死循环,什么都不干 | 返回去执行其他程序,过一段时间再来查 |
| CPU 利用率 | 0(全部耗在等待上) | 有提升 |
| 实时性 | 最好 | 取决于查询周期 |
| 代价 | CPU 完全被占 | 查询间隔不好定:太长会丢数据,太短又接近独占 |
定时查询是查询与中断之间的过渡形态,但它有一个中断没有的毛病:查询周期必须由程序员事先定死,而设备什么时候就绪是不可预测的。 这正是中断方式要解决的问题——把”什么时候来看”的决定权从 CPU 手里交给设备。
做题时如果题目只说”程序查询方式”而不加限定,默认按独占查询算。
CPU 占用率的计算
这是本节唯一的计算题型,模板固定。
已知:设备数据传输率
第一步,算出每秒要传送多少次:
第二步,算出一次传送花多少时间:
第三步,占用率:
一个算例。 某设备数据传输率
边界辨析:算出 0.4% 不等于"CPU 只被占了 0.4%"
这道题算的是”传送本身”的开销,不是”查询等待”的开销。
独占查询方式下,CPU 实际上是 100% 被占的——那 99.6% 的时间全花在”读状态、发现没好、再读”的循环里。上面的公式算的只是有效传送那一小部分。
两个数字回答的是两个不同的问题:
问法 答案 ”为该设备传送数据所花的 CPU 时间占比” 0.4%(用上面的公式) “独占查询方式下 CPU 有多少时间用在这台设备上” 100% “定时查询方式下呢” 传送 0.4% + 查询开销,取决于查询频率 审题的关键词:问”传送数据的时间”用公式;问”CPU 利用率/能不能干别的”看是不是独占查询。同一道题的两问经常一起出,答案一个是 0.4% 一个是 100%,看着矛盾其实不矛盾。
这个公式在 7.3.2 和 7.3.3 会以同样的形状再出现两次,只是
从 1 字节变成一个数据块, 变成中断开销或 DMA 预处理开销。三种方式的计算题是同一个模板换参数。
忙等不是阻塞
这是计组与操作系统之间口径最容易打架的一处。
| 忙等(busy waiting) | 阻塞(blocked) | |
|---|---|---|
| 进程状态 | 运行态 | 阻塞态 |
| CPU 在干什么 | 执行该进程的查询指令 | 执行别的进程 |
| 谁让它继续 | 循环条件自己成立 | 别的进程/中断把它唤醒 |
| 占不占 CPU | 占 | 不占 |
程序查询方式下,进程始终是运行态——它一直在执行”读状态、判断、跳转”这三条指令,从操作系统的角度看,这个进程一秒钟都没有让出 CPU。
“CPU 忙等所以进程阻塞”是彻底错误的:忙等的本质恰恰是”不阻塞”,它宁愿空转也不交出 CPU。OS 里进程转入阻塞态,用的是中断方式——发出 I/O 请求后主动放弃 CPU,等中断把自己唤醒。
两个词都带”等”,但一个占着 CPU 等,一个让出 CPU 等。
边界
| 说法 | 判断 | 理由 |
|---|---|---|
| ”查询方式下进程处于阻塞态” | ❌ | 运行态,一直在执行查询指令 |
| ”查询方式数据不经过 CPU” | ❌ | 设备→CPU 寄存器→主存 |
| ”查询方式需要中断请求触发器” | ❌ | 完全用不到 INTR/MASK |
| ”定时查询就没有忙等了” | ⚠️ | 减少了,但每次查询仍是忙等,只是次数变少 |
| ”查询方式实时性最差” | ❌ | 独占查询的实时性最好(一就绪立刻发现),差的是 CPU 利用率 |
| ”算出的 CPU 占用率 4‰ 说明 CPU 很空闲” | ❌ | 见上面的 callout:独占查询下 CPU 是 100% 被占的 |
| ”查询方式适合高速设备” | ❌ | 设备越慢,忙等越久,但设备越快对查询频率要求越高;查询方式适合的是低速且对成本敏感的场合 |
对照速查
| 量 | 公式 |
|---|---|
| 每秒传送次数 | |
| 一次传送耗时 | |
| 传送占用率 |
| 状态位 | 作用 |
|---|---|
| 设备忙,继续等 | |
| 设备就绪,可以传 |
考点
- CPU 占用率计算,注意区分”传送开销”与”独占 CPU”两问。
- 忙等 vs 阻塞——CO/OS 交叉考点。
- 数据流经过 CPU 寄存器。
- 独占查询与定时查询的区别。
链接
- 🏠 返回总览:计算机组成原理第 7 章:输入/输出系统总览
- ⬅️ 上一节:7.2.4 I/O 端口及其编址
- ➡️ 下一节:7.3.2 程序中断方式
- 🔗 四种方式对照:7.1.3 I/O 控制方式
- 🔗 状态触发器 B/D:7.2.2 I/O 接口的基本结构
- 💻 OS 对应:OS 5.1.2 I/O 控制方式
- 📖 名词库:第 7 章名词库