【Golang 面试题】每日 3 题(三十二)

devtools/2025/1/18 17:05:09/

✍个人博客:Pandaconda-CSDN博客
📣专栏地址:http://t.csdnimg.cn/UWz06
📚专栏简介:在这个专栏中,我将会分享 Golang 面试中常见的面试题给大家~
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪

94. Go 互斥的底层实现结构

互斥对应的是底层结构是 sync.Mutex 结构体,,位于 src/sync/mutex.go

go">type Mutex struct {state int32sema  uint32}

state 表示的状态,有定、被唤醒、饥饿模式等,并且是用 state 的二进制位来标识的,不同模式下会有不同的处理方式。

在这里插入图片描述

sema 表示信号量,mutex 阻塞队列的定位是通过这个变量来实现的,从而实现 goroutine 的阻塞和唤醒。

在这里插入图片描述

go">addr = &sema
func semroot(addr *uint32) *semaRoot {return &semtable[(uintptr(unsafe.Pointer(addr))>>3)%semTabSize].root
}
root := semroot(addr)
root.queue(addr, s, lifo)
root.dequeue(addr)
var semtable [251]struct {root semaRoot...
}
type semaRoot struct {lock  mutextreap *sudog // root of balanced tree of unique waiters.nwait uint32 // Number of waiters. Read w/o the lock.
}
type sudog struct {g *gnext *sudogprev *sudogelem unsafe.Pointer // 指向sema变量waitlink *sudog // g.waiting list or semaRootwaittail *sudog // semaRoot...
}

95. Go 互斥的操作

的实现一般会依赖于原子操作、信号量,通过 atomic 包中的一些原子操作来实现定,通过信号量来实现线程的阻塞与唤醒。

通过原子操作 cas 加,如果加不成功,根据不同的场景选择自旋重试加或者阻塞等待被唤醒后加

在这里插入图片描述

go">func (m *Mutex) Lock() {// Fast path: 幸运之路,一下就获取到了if atomic.CompareAndSwapInt32(&m.state, 0, mutexLocked) {return}// Slow path:缓慢之路,尝试自旋或阻塞获取m.lockSlow()
}

通过原子操作 add 解,如果仍有 goroutine 在等待,唤醒等待的 goroutine。

在这里插入图片描述

go">func (m *Mutex) Unlock() {// Fast path: 幸运之路,解new := atomic.AddInt32(&m.state, -mutexLocked)if new != 0 {// Slow path:如果有等待的goroutine,唤醒等待的goroutinem.unlockSlow()}}

96. Go 互斥的使用注意事项

  • 在 Lock() 之前使用 Unlock() 会导致 panic 异常。
  • 使用 Lock() 加后,再次 Lock() 会导致死(不支持重入),需 Unlock() 解后才能再加
  • 定状态与 goroutine 没有关联,一个 goroutine 可以 Lock,另一个 goroutine 可以 Unlock。

http://www.ppmy.cn/devtools/151608.html

相关文章

基于微信小程序的校园运动场地预约系统设计与实现

一.前言 选题背景: 随着社会的进步和人们生活水平的提高,健康意识逐渐增强,越来越多的人开始关注和参与体育运动。在校园中,学生们也积极参与各种体育活动,以提升身体素质和促进全面发展。然而,由于校园运动…

Linux一键巡检

文章目录 一、巡检内容 二、巡检结果展示 三、巡检脚本 四、执行脚本 五、查看巡检报告 六、设置定时任务 一、巡检内容 [1] 系统基本信息 [2] CPU 信息 [3] 内存使用情况 [4] 磁盘使用情况 [5] 网络配置和连接 [6] 服务状态检查 [7] 安全检查 [8] 登录记录 [9] 系统日志…

CSS的发展历程

本篇文章仅作为娱乐科普,如有错误,欢迎各位指正 目录 本篇文章仅作为娱乐科普,如有错误,欢迎各位指正 一、CSS的起源 二、CSS的发展 1、CSS1 2、CSS2 3、CSS2.1 4、CSS3 一、CSS的起源 在CSS出现之前,网页的设…

Spring MVC复杂数据绑定-绑定数组

【图书介绍】《SpringSpring MVCMyBatis从零开始学(视频教学版)(第3版)》_【新华文轩】springspring mvcmybatis从零开始学(视频教学版) 第3版 正版-CSDN博客 《SpringSpring MVCMyBatis从零开始学(视频教学版)(第3版…

VS Code--常用的插件

原文网址:VS Code--常用的插件_IT利刃出鞘的博客-CSDN博客 简介 本文介绍VS Code(Visual Studio Code)常用的插件。 插件的配置 默认情况下,插件会放到这里:C:\Users\xxx\.vscode\extensions 修改插件位置的方法 …

SpringMVC 请求参数接收

目录 请求 传递单个参数 基本类型参数传递 未传递参数 ?传递参数类型不匹配 传递多个参数 传递对象 后端参数重命名 传递数组 传递集合 传递JSON数据 JSON是什么 JSON的优点 传递JSON对象 获取URL中的参数 文件上传 在浏览器与程序进行交互时,主要…

进程的家园:探索 Linux 地址空间的奥秘

个人主页:chian-ocean 文章专栏-Linux 前言: 进程地址空间是操作系统为每个进程提供的一块独立的虚拟内存空间。每个进程的地址空间是独立的,确保了一个进程的运行不会直接影响其他进程的内存空间。 进程地址空间 进程地址空间是操作系统为…

鸿蒙中选择地区

1.首页ui import { CustomDialogExampleSelectRegion } from ./selectRegion/SelectRegionDialog;Entry Component struct Index {State selectedRegion: string 选择地区// 地区dialogControllerSelectRegion: CustomDialogController | null new CustomDialogController({b…