Appearance
题目
在下列同步机制中,可以实现让权等待的是( )。
错因
A
Peterson 是经典软件互斥方案,看起来"很正经"——但它的核心是 while (turn != me && flag[other]) ; 这种自旋等待:进程拿不到锁就在 while 上空转,CPU 没让给别人。"让权等待"要求主动让出 CPU 进阻塞队列,Peterson 做不到。
B
swap 指令(atomic exchange)是硬件原语,用法是 do { tmp = swap(lock, 1); } while (tmp == 1);——又是忙等。硬件原语只解决了原子性问题,没解决"等不到怎么办"——拿不到锁仍是循环试,没让权。
D
TestAndSet 同 swap,是另一个原子硬件指令:while (TestAndSet(lock)) ;,标准忙等模式。所有"硬件指令型"互斥方案天然不让权——它们的设计目标就是单纯的原子访问,不带阻塞队列管理。
总解析
并发同步的"准则四要素":空闲让进、忙则等待、有限等待、让权等待。最后一项要求进程在等不到资源时让出 CPU 进入阻塞态,而不是占着 CPU 空转。
把候选机制按"等不到时怎么处理"归类:
| 机制 | 等不到时的行为 | 是否让权? |
|---|---|---|
| Peterson 算法 | while 自旋检查标志位 | ✗(忙等) |
| swap / exchange 指令 | while (swap(lock, 1)==1) 循环 | ✗(忙等) |
| TestAndSet 指令 | while (TestAndSet(lock)) 循环 | ✗(忙等) |
| 信号量 P 操作 | 时把进程塞入信号量阻塞队列,调度器选别人跑 | ✓ 让权 |
判定原则:是否带"阻塞队列管理"是分水岭——能把等不到的进程从就绪/运行态挪到阻塞态,就让权;只能 while 等的就只能忙等。
信号量的 P 操作伪码:
P(S):
S = S - 1;
if (S < 0) block(S.queue); // 把当前进程移入阻塞队列,让出 CPU这里 block 就是让权的关键——OS 把进程状态改成阻塞态,调度器立刻去跑别人;将来对应 V 操作 wakeup(S.queue) 才把它放回就绪队列。
最终答案是 C。