程序查询方式

三种 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 占用率的计算

这是本节唯一的计算题型,模板固定。

已知:设备数据传输率 (B/s)、每次传送的数据量 (B)、每次传送需执行 条指令、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 寄存器。
  • 独占查询与定时查询的区别。

链接