前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >线程安全是否有什么办法检测到呢?

线程安全是否有什么办法检测到呢?

原创
作者头像
用户7365393
修改2021-10-08 14:12:54
修改2021-10-08 14:12:54
47800
代码可运行
举报
运行总次数:0
代码可运行

线程安全是否有什么办法检测到呢?

答案就是 data race tag,go 官方早在 1.1 版本就引入了数据竞争的检测工具,我们只需要在执行测试或者是编译的时候加上 -race 的 flag 就可以开启数据竞争的检测

使用方式如下

代码语言:javascript
代码运行次数:0
运行
复制
go test -race main.gogo build -race

不建议在生产环境 build 的时候开启数据竞争检测,因为这会带来一定的性能损失(一般内存5-10倍,执行时间2-20倍),当然 必须要 debug 的时候除外。 建议在执行单元测试时始终开启数据竞争的检测

2.1 示例一

执行如下代码,查看每次执行的结果是否一样

2.1.1 测试
  1. 代码 package main import ( "fmt" "sync") var wg sync.WaitGroupvar counter int func main() { // 多跑几次来看结果 for i := 0; i < 100000; i++ { run() } fmt.Printf("Final Counter: %d\n", counter)} func run() { // 开启两个 协程,操作 for i := 1; i <= 2; i++ { wg.Add(1) go routine(i) } wg.Wait()} func routine(id int) { for i := 0; i < 2; i++ { value := counter value++ counter = value } wg.Done()}
  2. 执行三次查看结果,分别是 Final Counter: 399950Final Counter: 399989Final Counter: 400000
  3. 原因分析:每一次执行的时候,都使用 go routine(i) 启动了两个 goroutine,但是并没有控制它的执行顺序,并不能满足顺序一致性内存模型。 当然由于种种不确定性,所有肯定不止这两种情况,
2.1.2 data race 检测

上面问题的出现在上线后如果出现bug会非常难定位,因为不知道到底是哪里出现了问题,所以我们就要在测试阶段就结合 data race 工具提前发现问题。

  1. 使用go run -race ./main.go
  2. 输出: 运行结果发现输出记录太长,调试的时候并不直观,结果如下main.main() D:/gopath/src/Go_base/daily_test/data_race/demo.go:14 +0x44==================Final Counter: 399987Found 1 data race(s)exit status 66

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 2.1 示例一
    • 2.1.1 测试
    • 2.1.2 data race 检测
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档