Appearance
题目
使用 TSL 指令实现进程互斥的伪代码如下。
C
do {
...
while (TSL(&lock));
critical section;
lock = FALSE;
...
} while (TRUE);下列与该实现机制相关的叙述中,正确的是( )。
错因
A
把 TSL 互斥误以为有阻塞队列——但这段伪码里没有任何"阻塞 / 唤醒"动作。等待者只是在 while 上自旋,根本没进任何队列;退出者只是 lock = FALSE,没有 wakeup 调用。误以为它有信号量那种 V 操作,没有看清自旋锁的极简结构。
C
让权等待要求"等不到时让出 CPU 进阻塞"——这段代码 while (TSL(&lock)); 是死循环忙等,CPU 一直握在自己手里。"满足让权等待"是反着说的。把"代码能跑就算让权"当作判定标准就错了。
D
把"执行 TSL 时关中断"误以为是必需。其实 TSL 指令本身是原子的(硬件保证读-改-写不可打断),不需要软件层面再加关中断。多 CPU 系统里关中断只挡本核中断,挡不住别核访问 lock,所以光靠关中断也保不了互斥;TSL 的原子性是硬件级的、跨核也成立。
总解析
TSL(Test-and-Set Lock)是硬件原子指令:原子地"读 lock、把 lock 置 1、返回原值"。while (TSL(&lock)) 的语义是:循环尝试拿锁,拿不到就一直试。
逐项核对:
| 选项 | 描述 | 判定 | 理由 |
|---|---|---|---|
| A | 退出者唤醒阻塞者 | ✗ | TSL 没有阻塞队列,等待者全在自旋,无人需要被唤醒 |
| B | 等待进程不主动放弃 CPU | ✓ | while (TSL(&lock)); 死循环检查,忙等——拿不到锁就一直占着 CPU 转,绝不主动让出 |
| C | 满足让权等待 | ✗ | 同 B——忙等是让权等待的反面 |
| D | TSL 应关中断 | ✗ | TSL 本身原子,硬件保证不可打断;额外关中断既不必要也对多核无效 |
让权等待 vs 忙等:
| 同步机制 | 等不到时怎么办 | 是否让权? |
|---|---|---|
| TSL / 自旋锁 | while 自旋检测 | ✗(忙等) |
| 信号量 P 操作 | 进入阻塞队列、调度别人 | ✓ |
| 管程 wait | 进入条件变量队列、调度别人 | ✓ |
关键判定:是否带"阻塞队列管理"——能把等不到的进程从就绪/运行态挪到阻塞态的,才是让权等待;只能 while 等的就只能忙等。
TSL 的优点是简单 + 短临界区时性能好(避免阻塞唤醒的上下文切换开销);缺点是长临界区下浪费 CPU。让权等待要靠信号量这类带阻塞队列的机制。
最终答案是 B。