581 字
3 分钟
互斥锁和自旋锁有什么区别?分别适合什么场景
互斥锁通常在竞争时让未获得锁的线程睡眠或阻塞,锁释放后再被唤醒;自旋锁则让等待者反复检查锁是否可用,持续占用 CPU。选择取决于临界区长度、竞争程度、线程能否睡眠以及实现环境。
若临界区极短、等待预计很快结束,且线程运行在不同 CPU 上,自旋可能省下阻塞和唤醒的调度成本。若持锁时间较长或竞争激烈,自旋会白白消耗 CPU,互斥锁通常更合适。自旋锁在单核上尤其容易浪费:持锁者若被等待者抢占,等待者持续占着唯一 CPU,持锁者反而无法运行并释放锁。
不要只按名字判断
用户态互斥锁在无竞争时可能完全在用户态快速完成,只有竞争时才进入内核等待;自旋也可能设置退避或短暂睡眠。操作系统内核中,自旋锁通常用于不能睡眠的上下文,而可睡眠的路径可用 mutex。具体约束取决于平台和锁实现,不能把“互斥锁一定系统调用、自旋锁一定更快”当成规律。
无论哪种锁,都要保证临界区内访问受保护数据的一致性。自旋锁持有期间不要执行可能睡眠的操作;互斥锁也不应跨越不必要的慢 I/O。锁获取顺序还必须一致以避免死锁。
常见追问
Q:自旋锁为什么可能比互斥锁快?
A:短等待时可以避免线程睡眠、唤醒和调度切换的成本;但若等待时间长,持续占用 CPU 会让整体吞吐下降。
Q:自旋锁适合单核机器吗?
A:通常不适合依赖持锁者并行运行的场景。等待线程可能占满唯一 CPU,使持锁者不能运行;实现可以通过调度策略或退避缓和,但不能假设自旋总有利。
Q:持有自旋锁时能调用会阻塞的函数吗?
A:不应这样做。阻塞时持锁者无法继续释放锁,其他 CPU 上的等待者会持续自旋,甚至造成系统停滞。
互斥锁和自旋锁有什么区别?分别适合什么场景
https://blog.xqcherry.top/posts/interview/operating-system/mutex-vs-spinlock/ 目录