Skip to content

考情分析

锁作为互斥的具体实现机制,408 真题中偶有涉及。属于 🔥 中低频考点。

前面的 TSL、Swap 等硬件方法都有忙等待的问题。锁是对这些底层机制的封装——自旋锁选择忙等,互斥锁选择阻塞,各有适用场景。

锁的概念

锁是实现互斥的最直接方式。一个锁只有两种状态:

  • 可用(unlocked):没有进程持有锁
  • 已占用(locked):某个进程正持有锁
acquire(lock);     // 获取锁(进入区)
临界区;
release(lock);     // 释放锁(退出区)

自旋锁(Spinlock)

自旋锁使用忙等待(busy waiting):获取锁失败时,在循环中反复检查锁的状态。就像在洗手间门口不停拧门把手试——如果里面的人马上出来还好,要是等很久就纯粹浪费体力。

c
// 基于 TSL 实现的自旋锁
void acquire(lock) {
    while (TestAndSet(&lock));  // 一直循环直到获取锁
}

void release(lock) {
    lock = false;
}
优点缺点
实现简单忙等待浪费 CPU 时间
不需要上下文切换不满足让权等待原则
适合临界区很短的情况不适合单处理机

互斥锁(Mutex Lock)

互斥锁使用阻塞/唤醒机制:获取锁失败时,进程被阻塞(让出 CPU),锁释放时唤醒等待的进程。

void acquire(lock) {
    if (lock 已被占用) {
        将自己加入等待队列;
        阻塞(block);
    }
    lock = 已占用;
}

void release(lock) {
    if (等待队列非空) {
        唤醒(wakeup)一个等待进程;
    }
    lock = 可用;
}
优点缺点
满足让权等待阻塞和唤醒有上下文切换开销
不浪费 CPU实现较复杂
适合各种场景

自旋锁 vs 互斥锁

特性自旋锁互斥锁
等待方式忙等待(循环检查)阻塞等待(让出 CPU)
CPU 开销等待期间持续占用 CPU等待期间不占 CPU
上下文切换
适用场景临界区很短、多处理机临界区较长、单处理机
让权等待不满足满足

考研高频考点

  • 🔥🔥 自旋锁和互斥锁的区别(忙等待 vs 阻塞)
  • 🔥 自旋锁不适合单处理机的原因
  • 🔥 互斥锁满足让权等待

锁只能解决互斥问题。当进程之间还有同步需求(先后顺序、资源计数)时,就需要更强大的工具——下一篇看信号量和 PV 操作。

真题练习

相关真题(2题)

2023Q45综合题7分

综合题:用swap指令实现临界区互斥的正确写法和原子性分析

2016Q27选择题2分

TSL忙等待:等待进程不会主动放弃CPU,不满足让权等待