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

【面试题】Golang之互斥锁与读写锁(第七篇)

在Go语言(Golang)中,锁是用来实现并发控制的一种机制,它可以帮助多个goroutine安全地访问共享资源,防止数据竞争和条件竞争的发生。Go标准库提供了多种锁的实现,其中最常见和最基本的包括互斥锁(Mutex)和读写锁(RWMutex)。

互斥锁(Mutex)

互斥锁是Go中最基本的锁类型,它确保了同一时刻只有一个goroutine能够访问某个资源。sync包中的Mutex类型提供了加锁(Lock)和解锁(Unlock)的方法。

import "sync" var ( mu sync.Mutex // 假设这里是某个共享资源 counter int ) func increment() { mu.Lock() // 加锁 // 临界区开始 counter++ // 临界区结束 mu.Unlock() // 解锁 }


在上面的例子中,increment函数在修改全局变量counter之前会先调用mu.Lock()进行加锁,确保在修改过程中没有其他goroutine能够访问counter。修改完成后,通过mu.Unlock()解锁,允许其他goroutine访问counter

读写锁(RWMutex)

读写锁是互斥锁的一种变体,它允许多个goroutine同时读取共享资源,但在写入资源时,会阻塞其他所有读取和写入的goroutine。sync包中的RWMutex类型提供了RLock(读锁)、RUnlock(释放读锁)、Lock(写锁)和Unlock(释放写锁)方法。

import "sync" var ( rwmu sync.RWMutex // 假设这里是某个共享资源 data map[string]int ) func readData(key string) int { rwmu.RLock() // 加读锁 defer rwmu.RUnlock() // 确保在函数结束时释放读锁 // 读取数据 return data[key] } func writeData(key, value string) { rwmu.Lock() // 加写锁 defer rwmu.Unlock() // 确保在函数结束时释放写锁 // 修改数据 data[key] = len(value) }

在上面的例子中,readData函数通过rwmu.RLock()加读锁,允许多个goroutine同时读取data,而不会相互阻塞。而writeData函数通过rwmu.Lock()加写锁,确保在写入过程中没有其他goroutine能够读取或写入data

注意事项

  • 使用锁时,要特别注意避免死锁的发生,即两个或多个goroutine相互等待对方释放锁的情况。
  • 锁的粒度应该尽量小,只锁定需要保护的关键部分,以提高程序的并发性能。
  • 锁的解锁操作应该放在加锁操作之后的每个退出路径上,通常通过defer语句来实现,以确保即使在发生错误时也能正确释放锁。
  • 在使用读写锁时,要注意写操作的频率和持续时间,因为写操作会阻塞所有的读操作和写操作,如果写操作过于频繁或持续时间过长,可能会导致读操作的性能下降。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【面试题】Redo log和Undo log
  • 【功能】DOTween动画插件使用
  • 【js自学打卡8】filter / 类与原型链 / 转字符串
  • 关于Mysql的面试题(实时更新中~)
  • Python 基础——元组
  • Unity UGUI 之 Graphic Raycaster
  • 珈和科技完成全国首个农险服务类数据产品入表,实现数据资产化
  • ModbusRTU转Profinet协议转化网关(建议收藏吖)
  • lua 游戏架构 之 SceneLoad场景加载(一)
  • 【Nacos】Nacos服务注册与发现 心跳检测机制源码解析
  • Unity UGUI 之EventSystem
  • PyTorch Autograd内部实现
  • RICHTEK立锜科技 WIFI 7电源参考设计
  • OCC 创建点线面体
  • js 只读对象
  • Android 初级面试者拾遗(前台界面篇)之 Activity 和 Fragment
  • Angular 响应式表单之下拉框
  • Docker 1.12实践:Docker Service、Stack与分布式应用捆绑包
  • echarts花样作死的坑
  • java正则表式的使用
  • js ES6 求数组的交集,并集,还有差集
  • JS基础之数据类型、对象、原型、原型链、继承
  • webpack项目中使用grunt监听文件变动自动打包编译
  • 闭包--闭包之tab栏切换(四)
  • 互联网大裁员:Java程序员失工作,焉知不能进ali?
  • 离散点最小(凸)包围边界查找
  • 码农张的Bug人生 - 见面之礼
  • 系统认识JavaScript正则表达式
  • 用Canvas画一棵二叉树
  • 自动记录MySQL慢查询快照脚本
  • # MySQL server 层和存储引擎层是怎么交互数据的?
  • ## 临床数据 两两比较 加显著性boxplot加显著性
  • ${ }的特别功能
  • (附源码)spring boot球鞋文化交流论坛 毕业设计 141436
  • (附源码)计算机毕业设计SSM智慧停车系统
  • (个人笔记质量不佳)SQL 左连接、右连接、内连接的区别
  • (利用IDEA+Maven)定制属于自己的jar包
  • (六)c52学习之旅-独立按键
  • (六)Flink 窗口计算
  • (三)elasticsearch 源码之启动流程分析
  • (原創) 如何動態建立二維陣列(多維陣列)? (.NET) (C#)
  • (转)Linq学习笔记
  • .net core使用ef 6
  • .net程序集学习心得
  • .vue文件怎么使用_vue调试工具vue-devtools的安装
  • ??如何把JavaScript脚本中的参数传到java代码段中
  • [ vulhub漏洞复现篇 ] AppWeb认证绕过漏洞(CVE-2018-8715)
  • [ vulhub漏洞复现篇 ] Jetty WEB-INF 文件读取复现CVE-2021-34429
  • []利用定点式具实现:文件读取,完成不同进制之间的
  • [1127]图形打印 sdutOJ
  • [2016.7.Test1] T1 三进制异或
  • [24年新算法]NRBO-XGBoost回归+交叉验证基于牛顿拉夫逊优化算法-XGBoost多变量回归预测
  • [AI 大模型] Meta LLaMA-2
  • [AIGC] SpringBoot的自动配置解析
  • [AIGC] 开源流程引擎哪个好,如何选型?