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

Golang互斥锁正常模式和饥饿模式的区别

Golang互斥锁(sync.Mutex)的正常模式和饥饿模式是两种不同的锁获取策略,旨在平衡性能和公平性。以下是两者的详细区别:

正常模式(非公平锁)

  1. 锁获取方式
    • 当一个goroutine持有锁时,其他goroutine会尝试通过自旋或阻塞等待锁释放。
    • 自旋是指goroutine在等待锁释放时不会立即阻塞,而是会循环检查锁的状态,以期望在锁被释放时立即获取到锁。
    • 如果自旋次数超过一定限制(如4次)或满足其他条件(如等待时间超过1毫秒、CPU核数大于1等),goroutine会进入阻塞状态,等待锁的持有者释放锁后唤醒。
  2. 等待队列
    • 所有等待锁的goroutine会按照先进先出(FIFO)的顺序排队等待。
    • 被唤醒的goroutine不会直接拥有锁,而是会和新请求锁的goroutine竞争锁。
    • 新请求锁的goroutine在CPU上执行,且可能有多个,因此刚刚唤醒的goroutine在锁竞争中可能失败。
  3. 性能特点
    • 正常模式下,锁的获取相对高效,因为goroutine可以通过自旋来减少阻塞和上下文切换的开销。
    • 但长时间等待锁的goroutine可能会因为无法获取到锁而切换到饥饿模式。

饥饿模式(公平锁)

  1. 锁获取方式
    • 当一个goroutine等待锁的时间超过一定阈值(如1毫秒)时,互斥锁会切换到饥饿模式。
    • 在饥饿模式下,新请求锁的goroutine不会参与抢锁,也不会进入自旋状态,而是直接进入等待队列的尾部。
    • 锁的所有权会直接交给等待队列中排在第一位的goroutine。
  2. 等待队列
    • 饥饿模式下,等待队列中的goroutine会按照顺序依次获取锁,避免了长时间等待锁的goroutine无法获取到锁的问题。
  3. 性能特点
    • 饥饿模式下,锁的获取更加公平,但性能会下降。
    • 因为新请求锁的goroutine需要等待队列中的其他goroutine获取到锁后才能获取锁,这增加了等待时间和上下文切换的开销。
    • 但饥饿模式可以避免因长时间等待锁而导致的高尾延时问题。

切换条件

  • 互斥锁会在以下情况下从正常模式切换到饥饿模式:
    1. 一个goroutine等待锁的时间超过1毫秒。
    2. 等待队列不为空,且新请求锁的goroutine在队列末尾或等待时间较短时,锁会尝试切换回正常模式。

使用建议

  • 在编写业务逻辑时,应尽量避免全局使用同一个Mutex,以减少锁竞争和等待时间。
  • 加锁后立即使用defer语句对其解锁,以避免死锁问题。
  • 根据具体业务场景选择合适的锁模式。如果业务场景对性能要求较高且可以容忍一定的不公平性,可以选择正常模式;如果对公平性要求较高且可以容忍一定的性能下降,可以选择饥饿模式。

综上所述,Golang互斥锁的正常模式和饥饿模式在锁获取策略、等待队列、性能特点等方面存在显著差异。开发者应根据具体业务场景和需求选择合适的锁模式以实现最佳性能和公平性。


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

相关文章:

  • Oracle Dataguard(主库为 Oracle 11g 单节点)配置详解(3):配置备用数据库
  • Halcon 显示异常
  • canvas+fabric实现时间刻度尺+长方形数据展示
  • 【保姆级】sql注入之堆叠注入
  • 《计算机网络A》单选题-复习题库
  • 解决 ffmpeg “Unknown encoder ‘hevc_nvenc‘“
  • 信息科技伦理与道德1:绪论
  • Java的基础概念(二)
  • MySQL中distinct和group by去重的区别
  • 力扣--LCR 167.招式拆解I
  • LeetCode7. 整数反转
  • 基于物联网的冻保鲜运输智能控制系统
  • MySQL实用SQL示例
  • 利用Java爬虫获取亚马逊国际按关键字搜索商品的实践指南
  • SQL偏移类窗口函数—— LAG()、LEAD()用法详解
  • Leetcode 从前序与中序遍历序列构造二叉树
  • B端UI设计规范是什么?
  • 汽车驾校转型做无人机执照培训详解, “驾” 起无人机培训新未来?
  • 大模型LLM-MMOE
  • leetcode 2658. 网格图中鱼的最大数目
  • 【20250101】Nature正刊:纯仿真强化学习得到外骨骼机器人的自适应控制策略
  • 深入浅出:Spring Boot 自定义消息转换器的实现与应用
  • 【单片机】NPN+PNP组成的高边开关无法完全关断
  • SpringBoot与Vue实现WebSocket心跳机制
  • 华为数通考试模拟真题(附带答案解析)题库领取
  • GAN对抗生成网络(二)——算法及Python实现