Appearance
题目
若 x 是管程内的条件变量,则当进程执行 x.wait() 时所做的工作是()。
错因
A
把"条件变量 x"误读成了一个需要互斥保护的共享变量。但条件变量根本不存数据,它只是一个等待队列的句柄——管程的整体互斥已由管程入口锁负责,wait 不是来加锁的。把它想成 P 操作(互斥信号量)是经典混淆。
B
把 wait 和 signal 的方向搞反了。signal/notify 才是唤醒队列里的某个进程,wait 是把自己挂上去。同一对操作的语义是反的:wait 是"我等",signal 是"我喊别人"。在不熟悉管程的情况下顺手往反方向选很常见。
C
误以为条件变量像信号量那样有"值"——大于 0 不阻塞、否则阻塞。但条件变量没有计数,wait 是无条件阻塞当前进程,不查任何值。"是否阻塞"由调用者在管程业务逻辑里用 if (条件不满足) cv.wait(); 自己判断,cv 自身不带状态。
总解析
条件变量 cv 是管程提供的同步原语,配合管程互斥锁使用。它的两个核心操作:
| 操作 | 语义 |
|---|---|
cv.wait() | 无条件阻塞当前进程,把它放入 cv 的阻塞队列;同时释放管程锁,让其他进程能进管程 |
cv.signal() / notify() | 从 cv 的阻塞队列里唤醒一个进程;被唤醒者重新竞争管程锁后继续执行 |
关键区别:信号量有计数,P 操作"判值再阻塞";条件变量无计数,wait 一定阻塞。
所以 x.wait() 做两件事:
- 把当前进程阻塞
- 把它插入条件变量 x 的阻塞队列
正好对应选项 D 的描述。
A 错(互斥不是 wait 的职责)、B 错(wait 不是唤醒)、C 错(条件变量没"值")。
最终答案是 D。