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

《Go小技巧易错点100例》第三十四篇

本期分享:

1.sync.Mutex锁复制导致的异常

2.Go堆栈机制下容易导致的并发问题


sync.Mutex锁复制导致的异常

以下代码片段存在一个隐蔽的并发安全问题:

type Counter struct {sync.MutexCount int
}func foo(c Counter) {c.Lock()defer c.Unlock()fmt.Println("in foo")
}func TestLock(t *testing.T) {var c Counterc.Lock()defer c.Unlock()c.Count++foo(c) // 复制锁
}

如果直接运行会出现异常:

fatal error: all goroutines are asleep - deadlock!

运行go vet .\code\code_34\lock_test.go工具会直接提示警告:

.\code\code_34\lock_test.go:12:14: call of foo copies lock value: .\code\code_34\lock_test.go:4:6 contains sync.Mutex

Go堆栈机制下容易导致的并发问题

先看下下面这段代码,猜一下会输出什么:

func f() {l := []int{1, 2, 3, 4, 5}  for _, i := range l {       go fmt.Println(i)        }                          
}                              

答案是:不确定

我们来分析下代码,每个go fmt.Println(i)会经历:

1)参数传递:将当前循环变量i的值拷贝到新goroutine的栈帧

2)上下文保存:创建新的G结构体(包含栈指针、PC等)

3)调度队列入队:将G加入全局运行队列或本地队列

4)上下文切换:可能触发当前M让出P,执行其他G

而这段代码的临时变量i存储在堆中,如果goroutine的执行在for循环结束,那么i的值就是5,此时输出则会是5 5 5 5 5,当然如果goroutine执行快,那输出就可能是1 2 3 4 5,因此是不确定的。

如果想要有正常1 2 3 4 5的输出,那么我们只需要把代码改为:

func f() {l := []int{1, 2, 3, 4, 5}  for _, i := range l {       go func(i int) {fmt.Println(i)  }(i)}                          
} 

就可以了。

http://www.lryc.cn/news/2393440.html

相关文章:

  • vue3+element-plus el-date-picker日期、年份筛选设置本周、本月、近3年等快捷筛选
  • Vue 技术文档
  • 3 分钟学会使用 Puppeteer 将 HTML 转 PDF
  • 速通《Sklearn 与 TensorFlow 机器学习实用指南》
  • Ubuntu 下搭建ESP32 ESP-IDF开发环境,并在windows下用VSCode通过SSH登录Ubuntu开发ESP32应用
  • [FreeRTOS- 野火] - - - 临界段
  • 【洛谷P9303题解】AC代码- [CCC 2023 J5] CCC Word Hunt
  • NodeMediaEdge接入NodeMediaServer
  • 【Java基础-环境搭建-创建项目】IntelliJ IDEA创建Java项目的详细步骤
  • WebSocket指数避让与重连机制
  • DrissionPage WebPage模式:动态交互与高效爬取的完美平衡术
  • adb查看、设置cpu相关信息
  • PHP7+MySQL5.6 查立得源码授权系统DNS验证版
  • 68元开发板,开启智能硬件新篇章——明远智睿SSD2351深度解析
  • 【QQ音乐】sign签名| data参数加密 | AES-GCM加密 | webpack (下)
  • 基于netmiko模块实现支持SSH or Telnet的多线程多厂商网络设备自动化巡检脚本
  • 不用 apt 的解决方案(从源码手动安装 PortAudio)
  • 【前端】JS引擎 v.s. 正则表达式引擎
  • 开发体育平台,怎么接入最合适的数据接口
  • 3D虚拟工厂
  • http传输协议的加密
  • 半导体晶圆制造洁净厂房的微振控制方案-江苏泊苏系统集成有限公司
  • 嵌入式(1):STM32 GPIO与AFIO深度解析:从原理到高阶应用实战
  • Netty 实战篇:Netty RPC 框架整合 Spring Boot,迈向工程化
  • QML视图组件ListView、TableView、GridView介绍
  • 常见压缩算法性能和压缩率对比 LZ4 LZO ZSTD SNAPPY
  • Spring Boot 应用中实现配置文件敏感信息加密解密方案
  • 【TTS】基于GRPO的流匹配文本到语音改进:F5R-TTS
  • 动态规划-152.乘积最大子数组-力扣(LeetCode)
  • 1-1 初探Dart编程语言