Sunday面试指南

互斥锁、自旋锁和信号量有什么区别?等待资源时该睡眠还是忙等?

🧑‍💻 面试官:互斥锁、自旋锁、信号量有什么区别?

🙋‍♂️ 我:都是锁,自旋锁更快。

🧑‍💻 面试官:持锁线程要等一个远程调用,你还会让其他线程原地自旋吗?

🙋‍♂️ 我:不会,那会浪费 CPU。

🧑‍💻 面试官:信号量初值为三,又是在保护一份互斥数据,还是限制三份资源?

互斥管独占,自旋描述等待方式,信号量管计数;先别把它们当成三个速度档位。

面试速答(60 秒版)

互斥锁主要提供独占临界区,并通常有持有者语义。自旋锁获取失败时反复检查,消耗 CPU,适合很短、能很快结束的临界区,不适合在持锁期间做耗时或阻塞操作。

信号量管理可用许可计数。计数为零时等待,释放后允许继续;初值三可以限制最多三个并发使用者。它不要求和互斥锁完全相同的持有者关系。

互斥锁也可能先短暂自旋再睡眠,具体实现要区分。因此选型不只是“一个阻塞、一个不阻塞”的口诀。

实际要看等待长度、竞争、调度环境和资源语义,同时控制锁范围、释放路径与加锁顺序。

互斥提供独占,自旋描述忙等,信号量管理有限许可

知识点详解:独占、等待与许可是三个角度

互斥的目标,是把相关修改保护成完整操作

假设两条线程同时对计数器读旧值、加一、写回,没有正确同步就可能丢掉更新。

互斥锁让同一时刻只有一个持有者进入所保护的区域。所有相关访问要遵守同一规则,只给写的一小半加锁,另一半仍然裸读写,并不完整。

锁有成本,也有语义要求。异常路径要释放,锁对象生命周期要安全;某些语言使用作用域管理,某些使用 try/finally,都比依赖调用者记得释放稳妥。

自旋把等候换成反复检查

自旋锁没拿到时,线程继续检查状态,少一次睡眠和唤醒的机会,但会占用执行资源。

假设持锁者只更新几个字段,很快释放,自旋可能值得评估。若持锁者等网络、磁盘或被长时间调度出去,其他线程忙等就没有意义。

单核、过度订阅和高竞争会改变收益。不能拿某次微小临界区测试推出所有服务都应使用自旋。用户态与内核态的限制也不能混着讲。

信号量是可消费和归还的许可

假设一个外部处理器只允许同时接收三个任务。初始化三份许可,每个任务开始前获取,结束后归还,就能限制并发。

这不意味着三个任务可以安全同时修改同一份非线程安全对象。限制并发和保护共享数据是两个问题,有时需要不同机制组合。

初值一的信号量可以实现某些互斥用途,但不能因此认定它就是有同样所有权、错误检测和优先级处理的互斥锁。

选型之前先检查锁内到底做了什么

先缩短临界区,避免把无关操作和远程等待放进去;再检查是否能用原子操作、消息传递或数据分片降低竞争。

多个锁需要约定统一顺序,超时也不能随意继续访问没保护的数据。可重入、公平性和优先级反转处理都依赖具体锁实现。

测试应看竞争下的吞吐和尾延迟,而不是只看无竞争获取一次花多久。发现忙等 CPU 高,不代表业务在高效工作。

本题机制参考:POSIX mutex、POSIX spin lock、POSIX semaphore。

面试官继续追问

互斥锁一定完全不自旋吗?

不一定。实现可能在短暂竞争时先自旋,再进入等待,接口语义和内部策略分开看。

有了信号量就不会死锁吗?

不会。许可获取顺序、未归还和相互等待仍可能出问题。

为什么锁中不建议调用远程接口?

不可控等待会延长所有竞争者的阻塞,还可能把下游故障放大为本地拥塞。

面试速记卡

  • 互斥:独占临界区,注意持有者规则。
  • 自旋:忙等方式,适合短等待而非永远更快。
  • 信号量:许可计数,控制资源使用。
  • 初值一:不意味着所有语义都等同互斥锁。
  • 工程:短临界区、可靠释放、统一顺序、竞争测试。

公司面试真题

真题根据求职者公开面经整理,题意经过概括,非逐字原话或公司官方题库;本文为 Sunday 的独立解析。

  • 腾讯 · 开发(含 Agent 设计) · 原帖未明确批次

    使用过哪些锁,各怎样工作?(题意整理)

    腾讯一面面经 ↗
    页面显示 04-20 发布,未明确年份

  • 字节跳动 · 后端(抖音) · 社招

    自旋锁怎样工作,线程上下文切换有什么开销?(题意整理)

    社招一年半面经分享 · 抖音部分 ↗
    历史面经,面试年份未明确;页面编辑于 2024-07-19

浏览公司面试真题 →
简历汪永久免费在线制作简历,模板直接套用、导出无水印,永久免费、下载免费,不需要付费解锁任何功能。去写简历