当前位置: 首页 > article >正文

linux中大内核锁、互斥锁、信号量、完成变量、自旋锁区别

大内核锁(BKL)互斥锁(Mutex)信号量(Semaphore)完成变量(Completion)自旋锁(Spinlock) 的详细对比,从特性、用途、优缺点等角度展开分析:


1. 核心特性对比

特性大内核锁(BKL)互斥锁(Mutex)信号量(Semaphore)完成变量(Completion)自旋锁(Spinlock)
保护范围全局锁,用于保护整个内核单一临界区单一或多个资源特定同步点单一临界区
等待机制阻塞等待阻塞等待阻塞等待阻塞等待忙等待(Busy Waiting)
适用场景内核大范围同步用户态或内核态简单同步多资源控制,复杂同步等待某些事件完成后继续运行临界区短、实时性高的同步场景
上下文切换
中断上下文支持是(如 spin_lock_irqsave
嵌套锁支持不建议嵌套可嵌套(有递归锁支持)可嵌套不适合嵌套不适合嵌套
是否线程安全

2. 优缺点对比

类型优点缺点
大内核锁(BKL)- 实现简单。
- 在早期单核系统中可用性高。
- 粒度太粗,导致性能瓶颈,无法适应多核环境。
互斥锁(Mutex)- 允许任务睡眠,节省 CPU 资源。
- 支持递归锁,适合复杂场景。
- 不适合中断上下文。
- 可能造成死锁,需要正确管理锁的释放。
信号量(Semaphore)- 控制多资源访问,灵活性高。
- 支持线程间、进程间同步。
- 复杂度较高,容易导致资源泄露(如忘记释放信号量)。
完成变量(Completion)- 适合等待异步事件完成。
- 实现简单,针对性强。
- 功能单一,只适用于特定同步场景。
自旋锁(Spinlock)- 实时性好,适合短临界区。
- 可用于中断上下文。
- 避免上下文切换的开销。
- 忙等待可能浪费 CPU 时间。
- 不适合长时间持锁,会导致性能下降。

3. 使用场景

场景推荐锁类型理由
简单同步,临界区短自旋锁(Spinlock)避免上下文切换,提供高实时性,适合短时间内访问共享资源。
复杂同步,允许挂起互斥锁(Mutex)或信号量(Semaphore)互斥锁适合单资源同步,信号量适合控制多个资源访问。
中断上下文或中断处理函数自旋锁(Spinlock)自旋锁支持中断上下文,而其他锁不支持。
等待异步事件完成完成变量(Completion)直接调用 wait_for_completion(),直到事件完成,代码逻辑清晰简单。
简单资源计数(如线程池资源)信号量(Semaphore)适用于多资源计数同步,减少同步逻辑的复杂度。
全局同步,代码老旧大内核锁(BKL)在老旧代码中(如 Linux 2.4),可以用 BKL,但已经逐步淘汰,不推荐新开发使用。

4. 特殊机制

大内核锁(BKL):
  • 是一种全局锁,用于保护整个内核的共享数据,锁粒度较大。
  • 在早期 Linux 内核中(如 2.4 版本),BKL 是同步的主要方式,但在多核系统中表现不佳。
  • 从 Linux 2.6 开始逐步被替代,目前已完全移除。
互斥锁(Mutex):
  • 锁拥有者有线程所有权,只有加锁的线程可以解锁。
  • 支持阻塞等待,任务睡眠时可以让出 CPU。
  • 提供递归锁(Recursive Mutex),允许同一线程多次加锁。
信号量(Semaphore):
  • 计数信号量可以控制多个线程同时访问资源。
  • 适合线程或进程间同步,如生产者-消费者问题。
  • 支持阻塞等待,但需要小心避免死锁或信号量泄露。
完成变量(Completion):
  • 常用于等待硬件或异步操作完成。
  • 提供简单的 API,如 complete()wait_for_completion(),易于使用。
  • 功能较单一,仅适合同步某些特定的完成事件。
自旋锁(Spinlock):
  • 使用忙等待,锁竞争时不会触发任务调度。
  • 可用于中断上下文,如 spin_lock_irqsave() 会禁用中断。
  • 不适合长时间持锁,否则会浪费 CPU 时间。

5. 锁的开销和性能

锁类型上下文切换开销加锁/解锁时间资源利用率适用复杂度
大内核锁(BKL)低(全局锁)
互斥锁(Mutex)高(任务可睡眠)中等
信号量(Semaphore)中(多资源管理能力强)
完成变量(Completion)高(同步事件完成)
自旋锁(Spinlock)中(短临界区资源利用率高)中等

6. 总结

类型适用场景
大内核锁(BKL)老旧代码或非常简单的同步需求,不推荐用于现代开发。
互斥锁(Mutex)临界区复杂、锁持有时间长、允许任务挂起的场景,如文件系统、用户态与内核态同步。
信号量(Semaphore)资源控制复杂(如线程池、生产者-消费者模型)或需要多资源共享的场景。
完成变量(Completion)等待特定事件(如硬件操作或异步任务完成)时使用,提供高效的同步机制。
自旋锁(Spinlock)高实时性、短临界区的同步场景,尤其是在中断上下文或多核系统中。

通过合理选择锁类型,可以提升系统性能,降低同步复杂度。


http://www.kler.cn/a/446987.html

相关文章:

  • 常用的JVM启动参数有哪些?
  • 使用CNN模型训练图片识别(键盘,椅子,眼镜,水杯,鼠标)
  • Word图片嵌入格式不正确的解决办法
  • RestTemplate远程调用、服务注册、
  • libmodbus安装使用
  • ES搜索原理
  • 【AIGC-ChatGPT进阶提示词-《动图生成》】怪物工厂:融合想象力与创造力的奇幻世界
  • vscode 使用说明
  • 四川托普信息技术职业学院教案1
  • 智能挂号系统设计典范:SSM 结合 Vue 在医院的应用实现
  • Windows下安装Rabbit MQ
  • 【线性代数】理解矩阵乘法的意义(点乘)
  • 安装Mac软件遇到问题常见报错
  • 机器学习-逻辑回归和softmax回归
  • go语言zero框架中启动脚本.sh的编写与配置
  • go语言 爬虫 钉钉群机器人
  • 玩游戏没有flash插件的解决方案(No Flash)
  • 【RAII | 设计模式】C++智能指针,内存管理与设计模式
  • 音视频入门基础:MPEG2-TS专题(21)——FFmpeg源码中,获取TS流的视频信息的实现
  • python学习笔记—9—复习
  • 详细介绍如何使用rapidjson读取json文件
  • 《向量数据库指南》——RAG破局,大模型新纪元!
  • EasyGBS国标GB28181平台P2P远程访问故障排查指南:客户端角度的排查思路
  • 半导体数据分析(二):徒手玩转STDF格式文件 -- 码农切入半导体系列
  • MyBatis写法汇总
  • 写给Pythoner的前端进阶指南(六):网络编程