MST

星途 面试题库

面试题:并发与同步:锁竞争对系统性能的影响及平衡方法

在多线程编程环境中,简单描述锁竞争是如何产生的?它对系统性能可能会带来哪些具体开销?列举至少两种在实际项目中平衡锁竞争与性能开销的常见策略。
32.3万 热度难度
操作系统并发与同步

知识考点

AI 面试

面试题答案

一键面试

锁竞争的产生

在多线程编程中,当多个线程试图同时访问并修改共享资源时,就会产生锁竞争。每个线程在访问共享资源前需要先获取对应的锁,如果一个线程已经持有了锁,其他线程就必须等待该锁被释放,这些等待获取锁的线程之间就形成了锁竞争。

对系统性能的具体开销

  1. CPU 时间浪费:等待锁的线程处于阻塞状态,但仍占用系统资源,CPU 需要不断调度线程上下文,造成额外的 CPU 开销。
  2. 线程上下文切换开销:当线程因无法获取锁而被阻塞,操作系统需要保存该线程的当前状态,并切换到其他可运行的线程。这个过程涉及寄存器值的保存与恢复、内存映射的切换等操作,消耗时间和资源。
  3. 吞吐量下降:由于线程等待锁,整体任务的执行进度变慢,系统的吞吐量(单位时间内完成的任务数量)会降低。

平衡锁竞争与性能开销的常见策略

  1. 减小锁粒度
    • 描述:将大的锁保护范围分割成多个小的锁,每个锁只保护一小部分共享资源。这样,不同线程可以同时访问不同部分的共享资源,减少锁竞争的可能性。
    • 示例:在一个包含多个数据项的哈希表中,如果使用一个大锁保护整个哈希表,每次只有一个线程能访问。若为每个哈希桶设置单独的锁,不同线程可以同时访问不同哈希桶的数据,提高并发度。
  2. 锁分段
    • 描述:类似减小锁粒度,把共享资源按照某种规则(如数据范围、功能模块等)分成多个段,每个段使用独立的锁进行保护。
    • 示例:在一个数据库表中,按照记录的 ID 范围划分成多个段,不同线程对不同 ID 范围的记录操作时,可以同时获取各自段的锁,降低锁竞争。
  3. 读写锁分离
    • 描述:如果共享资源的操作以读为主,写操作为辅,可以使用读写锁。读操作可以并发执行,因为读操作不会修改共享资源状态,不会产生数据不一致问题;而写操作则需要独占锁,以保证数据的一致性。
    • 示例:在一个缓存系统中,多个线程频繁读取缓存数据,偶尔有线程更新缓存。此时可以使用读写锁,读操作使用读锁并发执行,写操作使用写锁独占执行。