Go语言sync.Mutex包源码解读

互斥锁sync.Mutex是在并发程序中对共享资源进行访问控制的主要手段,对此Go语言提供了非常简单易用的机制。sync.Mutex为结构体类型,对外暴露Lock()、Unlock()、TryLock()三种方法,分别用于阻塞加锁、解锁、非阻塞加锁操作(加锁失败后快速返回结果不会陷入阻塞状态)。

sync.Mutex内部实现比较复杂,但是坚持阅读之后,却有很大的收益。比如如何设计一个任务调度系统,每个时间点只有一个任务执行,在调度任务时,既需要保证任务执行的效率也需要保证一个任务不会出现饿死的情况,sync.Mutex的内部机制可能会给你一些借鉴经验。除此之外,还能够让你对TryLock有更加深刻的理解和在使用Mutex时的注意点。

版本:go1.24.1

数据结构

//package: pakcage:src\internal\sync\mutex.gotype Mutex struct {state int32sema  uint32
}const (mutexLocked = 1 << iota // mutex is lockedmutexWokenmutexStarvingmutexWaiterShift = iotastarvationThresholdNs = 1e6
)

Mutex结构比较简单,定义了两个字段:

  • state:根据bit位的划分,表示多种含义。
  • sema:信号量,用于管理协程阻塞和唤醒的关键机制,确保协程高效调度和唤醒。

state字段通过分割比特位来表示三种状态和记录当前等待获取锁的协程数量,从低位到高位依次为:

  • mutexLocked:1bit位,当前mutex是否被锁定,0表示未锁定,1表示锁定。
  • mutexWoken:1bit位,当前是否有协程从阻塞中被唤醒,0表示未被唤醒,1表示有协程被唤醒。
  • mutexStarving:1bit位,当前mutex的所处模式,0表示正常模式,1表示饥饿模式。
  •  mutexWaiterShift:位偏移量,利用偏移后的位来记录等待协程的数量,占用29bit位。

两种模式

正常模式和饥饿模式是sync.mutex包的精髓,通过这两种模式来保证性能和公平。

  • 正常模式:追求性能,允许新的协程通过自旋和竞争来快速获取锁,减少协程的上下文切换开销。
  • 饥饿模式:兜底公平性,确保等待者不被饿死。

在正常模式下,等待者按FIFO顺序排队,但被唤醒的等待者不拥有mutex,并与新到达的goroutines竞争所有权。而新加入的goroutines有一个优势——它们已经在CPU上运行,并且可能有很多,所以唤醒的等待者很有可能会失败。在这种情况下,它被排在等待队列的前面。如果等待者获得mutex的时间超过1ms,将mutex将切换到饥饿模式。

在饥饿模式下,mutex的所有权直接从正在解锁的goroutine移交(hand off)给队列前面的等待者。新到达的goroutines不会尝试获取mutex,即使mutex已经解锁,(新到达的goroutines)也不会尝试自旋。相反,它们把自己排在等待队列的尾部。如果一个等待者获得了mutex的所有权,并且发现以下任一条件:(1)它是队列中最后一个等待者;(2)它等待的时间少于1毫秒;那么mutex将切换回正常工作模式。

源码解读

请访问github仓库,以注释的方式进行解读,提高阅读体验和保证思考的连续性。

仓库地址:wuqiong818/go-source-interpretation: go语言解读

参考文章

Go1.24.1源码

Go专家编程 sync.Mutex章节

【Go万字洗髓经】Golang中sync.Mutex的单机锁:实现原理与底层源码-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/77240.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SQL注入流量分析

免责声明&#xff1a;本文仅作分享 ~ 目录 SQL注入流量分析 特征&#xff1a; sqlmap注入类型 漏洞环境搭建 error_sql: bool_sql: time_sql: union_sql: Stacked Queries: Inline Queries: SQL注入流量分析 https://www.freebuf.com/column/161797.html SQLMAP攻击…

Linux 时间同步工具 Chrony 简介与使用

一、Chrony 是什么&#xff1f; chrony 是一个开源的网络时间同步工具&#xff0c;主要由两个组件组成&#xff1a; chronyd&#xff1a;后台服务进程&#xff0c;负责与时间服务器交互&#xff0c;同步系统时钟。chronyc&#xff1a;命令行工具&#xff0c;用于手动查看或修…

Flutter:Flutter SDK版本控制,fvm安装使用

1、首先已经安装了Dart&#xff0c;cmd中执行 dart pub global activate fvm2、windows配置系统环境变量 fvm --version3、查看本地已安装的 Flutter 版本 fvm releases4、验证当前使用的 Flutter 版本&#xff1a; fvm flutter --version5、切换到特定版本的 Flutter fvm use …

Vue 项目中的package.json各部分的作用和用法的详细说明

1. 基本信息 {"name": "my-vue-app","version": "1.0.0","description": "A Vue.js project","author": "Your Name <your.emailexample.com>","license": "MIT"…

Linux网络编程——TCP通信的四次挥手

一、前言 上篇文章讲到了TCP通信建立连接的“三次握手”的一些细节&#xff0c;本文再对TCP通信断开连接的“四次挥手”的过程做一些分析了解。 二、TCP断开连接的“四次挥手” 我们知道TCP在建立连接的时需要“三次握手”&#xff0c;三次握手完后就可以进行通信了。而在通…

某碰瓷国赛美赛,号称第三赛事的数模竞赛

首先我非常不能理解的就是怎么好意思自称第三赛事的呢&#xff1f;下面我们进行一个简单讨论&#xff0c;当然这里不对国赛和美赛进行讨论。首先我们来明确一点&#xff0c;比赛的含金量由什么来定&#xff1f;这个可能大家的评价指标可能不唯一&#xff0c;我通过DeepSeek选取…

Redis 缓存问题:缓存雪崩、缓存击穿、缓存穿透

文章目录 缓存雪崩缓存击穿缓存穿透在实际的业务场景中,Redis 通常作为缓存和其他数据库(例如 MySQL)搭配使用,用来减轻数据库的压力。但是在使用 Redis 作为缓存数据库的过程中,可能会遇到一些常见问题,例如缓存穿透、缓存击穿和缓存雪崩等。 缓存雪崩 缓存雪崩是指缓存…

Qt 入门 4 之标准对话框

Qt 入门 4 之标准对话框 Qt提供了一些常用的对话框类型,它们全部继承自QDialog类,并增加了自己的特色功能,比如获取颜色、显示特定信息等。下面简单讲解这些对话框,可以在帮助索引中查看Standard Dialogs关键字,也可以直接索引相关类的类名。 本文将以一个新的项目为主介绍不…

买不起了,iPhone 或涨价 40% ?

周知的原因&#xff0c;新关税对 iPhone 的打击&#xff0c;可以说非常严重。 根据 Rosenblatt Securities分析师的预测&#xff0c;若苹果完全把成本转移给消费者。 iPhone 16 标配版的价格&#xff0c;可能上涨43%。 iPhone 16 标配的价格是799美元&#xff0c;上涨43%&am…

软件需求分析习题汇编

需求工程练习题 一、选择题 1. 软件需求规格说明书的内容不应包括对&#xff08; &#xff09;的描述。 A. 主要功能B. 算法的详细过程C. 用户界面及运行环境D. 软件的性能 *正确答案:*B:算法的详细过程; 2. 需求分析最终结果是产生&#xff08; &#xff09; A. 项目开发…

clickhouse注入手法总结

clickhouse 遇到一题clickhouse注入相关的&#xff0c;没有见过&#xff0c;于是来学习clickhouse的使用&#xff0c;并总结相关注入手法。 环境搭建 直接在docker运行 docker pull clickhouse/clickhouse-server docker run -d --name some-clickhouse-server --ulimit n…

智能语音识别工具开发手记

智能语音识别工具开发手记 序言&#xff1a;听见数字化的声音 在县级融媒体中心的日常工作中&#xff0c;我们每天需要处理大量音频素材——从田间地头的采访录音到演播室的节目原声&#xff0c;从紧急会议记录到专题报道素材。二十多年前&#xff0c;笔者刚入职时&#xff0…

TDengine 3.3.6.0 版本中非常实用的 Cols 函数

简介 在刚刚发布的 TDengine 3.3.6.0 版本 中&#xff0c;新增了一个非常实用的 函数COLS &#xff0c;此函数用于获取选择函数所在行列信息&#xff0c;主要应用在生成报表数据&#xff0c;每行需要出现多个选择函数结果&#xff0c;如统计每天最大及最小电压&#xff0c;并报…

【AI学习】AI Agent(人工智能体)

1&#xff0c;AI agent 1&#xff09;定义 是一种能够感知环境、基于所感知到的信息进行推理和决策&#xff0c;并通过执行相应动作来影响环境、进而实现特定目标的智能实体。 它整合了多种人工智能技术&#xff0c;具备自主学习、自主行动以及与外界交互的能力&#xff0c;旨…

【MCP】VSCode Cline配置MongoDB连接

VSCode MCP插件配置MongoDB连接教程 前言 本文将介绍如何在VSCode中配置Cline插件连接MongoDB。 环境准备 VSCodeNode.jsMongoDB服务器Cline插件 配置步骤 1. 安装MCP插件 在VSCode扩展商店中搜索"Cline"并安装。 安装完之后需要配置API平台以及设置API-KEY。…

this指针 和 类的继承

一、this指针 Human类的属性fishc与Human&#xff08;&#xff09;构造器的参数fishc同名&#xff0c;但却是两个东西。使用this指针让构造器知道哪个是参数&#xff0c;哪个是属性。 this指针&#xff1a;指向当前的类生成的对象 this -> fishc fishc当前对象&#xff08;…

使用PyTorch训练VGG11模型:Fashion-MNIST图像分类实战

本文将通过代码实战&#xff0c;详细讲解如何使用 PyTorch 和 VGG11 模型在 Fashion-MNIST 数据集上进行图像分类任务。代码包含数据预处理、模型定义、训练与评估全流程&#xff0c;并附上训练结果的可视化图表。所有代码可直接复现&#xff0c;适合深度学习初学者和进阶开发者…

汽车BMS技术分享及其HIL测试方案

一、BMS技术简介 在全球碳中和目标的战略驱动下&#xff0c;新能源汽车产业正以指数级速度重塑交通出行格局。动力电池作为电动汽车的"心脏"&#xff0c;其性能与安全性不仅直接决定了车辆的续航里程、使用寿命等关键指标&#xff0c;更深刻影响着消费者对电动汽车的…

打造船岸“5G+AI”智能慧眼 智驱力赋能客船数智管理

项目介绍 船舶在航行、作业过程中有着严格的规范要求&#xff0c;但在实际航行与作业中往往会因为人为的疏忽&#xff0c;发生事故&#xff0c;导致人员重大伤亡和财产损失&#xff1b; 为推动安全治理模式向事前预防转型&#xff0c;实现不安全状态和行为智能预警&#xff0c…

C#二叉树

C#二叉树 二叉树是一种常见的数据结构&#xff0c;它是由节点组成的一种树形结构&#xff0c;其中每个节点最多有两个子节点。二叉树的一个节点通常包含三部分&#xff1a;存储数据的变量、指向左子节点的指针和指向右子节点的指针。二叉树可以用于多种算法和操作&#xff0c;…