Appearance
题目
系统中有 8 个进程,执行下图的操作,资源 S 的初始值为 5。若此时 S 的值为 -2,其中 m 表示执行到访问资源的进程个数,n 表示阻塞的进程个数,则 m 和 n 的值分别是( )。
C
操作
wait(S)
访问资源
signal(S)错因
B
阻塞数算错。把" 等于阻塞队列长度"的规则记成了"S 减小到负多少就是 "——可能是把"第一个变成负数的那次 wait"这一步漏算了。实际上 S 每次变负后绝对值都精确等于此时阻塞的进程数:S=−1 → 1 个阻塞;S=−2 → 2 个阻塞。
C
把"还能容纳几个进程访问"和"已经在访问的进程数"搞混。看到 S 初始为 5、有 8 个进程,下意识算成" 个还在跑"——但临界区容量被信号量初值 5 卡死了,最多同时只有 5 个进程能"访问",多出来的全部阻塞。 没有任何意义。
D
误以为 8 个进程都已执行 wait 而进入临界区或阻塞,且按 凑了 m。但 wait 操作每次让 S 减 1:从 5 减到 -2 实际只发生了 7 次 wait(一个进程还没轮到),并不是 8 次都执行了。同时阻塞数应是 ,不是 1。两个数都错。
总解析
信号量语义回顾(这两条是这题的全部):
wait(S):先S--;若S < 0,调用进程阻塞进入 S 的等待队列;若S ≥ 0,进程继续执行进入临界区- 信号量为负时, 恰好等于阻塞队列上的进程数——这是判断阻塞数最快的捷径
逐步推导:
| 状态 | S 值 | 累计 wait 次数 | 已访问 | 阻塞 | 还未来 |
|---|---|---|---|---|---|
| 初始 | +5 | 0 | 0 | 0 | 8 |
| 第 1 个 wait | +4 | 1 | 1 | 0 | 7 |
| 第 2 个 wait | +3 | 2 | 2 | 0 | 6 |
| 第 3 个 wait | +2 | 3 | 3 | 0 | 5 |
| 第 4 个 wait | +1 | 4 | 4 | 0 | 4 |
| 第 5 个 wait | 0 | 5 | 5 | 0 | 3 |
| 第 6 个 wait | −1 | 6 | 5 | 1 | 2 |
| 第 7 个 wait | −2 | 7 | 5 | 2 | 1 |
到 S = −2 时:
- = 当前在临界区访问资源的进程数 = 5(这正是信号量初值——临界区"容量"被 5 卡死,无法多于 5)
- = 阻塞队列长度 = = 2
两条速记结论:
- 为正时:表示剩余可用资源数
- 为负时: 表示阻塞队列长度;同时正在访问资源的进程数已达初值上限
最终答案是 A(5, 2)。