Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >线程安全是否有什么办法检测到呢?

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

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

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

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

使用方式如下

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Go:深入解析internal/race包,数据竞争检测的利器
在 Go 语言中,internal/race 包是用于支持数据竞争检测的内部包。数据竞争(data race)是并发编程中常见且棘手的问题,通常发生在多个 goroutine 并发访问共享变量且至少有一个访问是写操作时。如果不加以控制,数据竞争可能导致程序行为不可预测、难以调试和修复。
运维开发王义杰
2024/05/28
3810
Go:深入解析internal/race包,数据竞争检测的利器
Go语言中常见100问题-#71 Misusing sync.WaitGroup
sync.WaitGroup是一种等待n个操作完成的机制,通常,我们使用它来等待n个goroutine完成。下面将学习它的使用方法,然后将看到一个高频错误使用问题,以及这个问题导致的不确定性行为。
数据小冰
2022/08/15
3290
Go语言中常见100问题-#71 Misusing sync.WaitGroup
Go并发编程里的数据竞争以及解决之道
Go语言以容易进行并发编程而闻名,但是如果稍不注意,并发程序可能导致的数据竞争问题(data race)就会经常出现在你编写的并发程序的待解决Bug列表中-- 如果你不幸在代码中遇到这种错误,这将是最难调试的错误之一。
KevinYan
2020/05/28
2.8K0
【Go】资源竟态检测工具:race detetor
试了一下,简直牛逼。鉴于处于快速入门阶段,就不去挖底层原理了,等面铺开了再深入。 用一个有点并发经验的人都能看出来的例子,累加: package main import ( "fmt" "sync" ) func main() { var count = 0 // 使用WaitGroup等待10个goroutine完成 var wg sync.WaitGroup wg.Add(10) for i := 0; i < 10; i++ { go func() { defer wg.D
看、未来
2022/06/19
1830
Go语言实战笔记(十七)| Go 读写锁
前面的有篇文章在讲资源竞争的时候,讲互斥锁,互斥锁的根本就是当一个goroutine访问的时候,其他goroutine都不能访问,这样肯定保证了资源的同步,避免了竞争,不过也降低了性能。
飞雪无情
2018/08/28
3740
GO系列(4)-goroutine基本用法
runtime 调度器是个非常有用的东西,关于 runtime 包几个方法:
爽朗地狮子
2022/10/20
3120
Go基础——Goroutine
创建时默认的stackd的大小 JDK5以后Java Thread stack默认的是1M Groutine 的stack初始化为2K KSE(kernel space entity)的对应关系 Java Thread是1:1 Groutine 的是M:N
羊羽shine
2019/05/29
5810
[Go] golang的竞争状态
2.竞争状态:两个或者多个goroutine在没有互相同步的情况下,访问某个共享的资源,并试图同时读和写这个资源,就处于互相竞争的状态 对共享资源的读和写操作必须是原子化的,同一时刻只能有一个goroutine对共享资源进行读和写操作
唯一Chat
2019/09/10
5230
[Go] golang的竞争状态
Go语言并发常见问题:A-Study-of-Real-World-Data-Races-in-Golang
data race的检测可以通过go build中加入-race来进行。详情见此文所举的例子
千灵域
2022/06/17
6430
Go语言并发常见问题:A-Study-of-Real-World-Data-Races-in-Golang
Golang sync.WaitGroup 简介与用法
sync.WaitGroup 用于阻塞等待一组 Go 程的结束。主 Go 程调用 Add() 来设置等待的 Go 程数,然后该组中的每个 Go 程都需要在运行结束时调用 Done(), 递减 WaitGroup 的 Go 程计数器 counter。当 counter 变为 0 时,主 Go 程被唤醒继续执行。
恋喵大鲤鱼
2019/08/01
1.9K0
golang 系列:waitgroup 解析
Golang 提供了简洁的 go 关键字来让开发者更容易的进行并发编程,同时也提供了 WaitGroup 对象来辅助并发控制。今天我们就来分析下 WaitGroup 的使用方法,顺便瞧一瞧它的底层源码。
lincoln
2021/08/15
7140
避坑:Go并发编程时,如何避免发生竞态条件和数据竞争
现在,我们已经知道了。在编写并发程序时,如果不谨慎,没有考虑清楚共享资源的访问方式和同步机制,那么就会发生竞态条件和数据竞争这些问题,那么如何避免踩坑?避免发生竞态条件和数据竞争的办法有哪些?请看下面:
不背锅运维
2023/04/25
1.1K0
避坑:Go并发编程时,如何避免发生竞态条件和数据竞争
Go的append操作是线程安全的吗
“ 根据golang中slice的数据结构可知,slice依托数组实现,在底层数组容量充足时,append操作不是只读操作,会将元素直接加入数组的空闲位置。因此,在多协程 对全局slice进行append操作时,会操作同一个底层数据,导致读写冲突”
Go学堂
2023/01/31
1.4K0
Go 语言互斥锁
在并发编程中,互斥锁(Mutex,全称 Mutual Exclusion)是一个重要的同步原语,用于确保多个线程或进程在访问共享资源时不会发生竞态条件。竞态条件是指在多个线程同时访问或修改共享数据时,由于操作顺序的不确定性,导致数据不一致或者程序行为不可预测的问题。
FunTester
2025/02/19
1290
Go 语言互斥锁
《GO IN ACTION》读后记录:GO的并发与并行
一、使用goroutine来运行程序 1. Go的并发与并行 Go的并发能力,是指让某个函数独立于其他函数运行的能力。当为一个函数创建goroutine时,该函数将作为一个独立的工作单元,被 调度器 调度到可用的逻辑处理器上执行。Go的运行时调度器是个复杂的软件,它做的工作大致是: 管理被创建的所有goroutine,为其分配执行时间 将操作系统线程与语言运行时的逻辑处理器绑定 参考The Go scheduler ,这里较浅显地说一下Go的运行时调度器。操作系统会在物理处理器上调度操作系统线程来运行,而G
李海彬
2018/03/28
9990
《GO IN ACTION》读后记录:GO的并发与并行
多协程写同一个slice的最佳实践
测试命令为go run -race main.go,会发生数据竞争。其中在append的时候会发生两种竞争,一个是slice的容量增加时会发生问题,另一个是单纯读写时也会发生问题。 这使得最终的长度总是小于预期。
千灵域
2022/06/17
7390
Go语言入门(八)线程安全&锁
线程安全&锁 定时器&一次性定时器 定时器 func main() { ticker := time.NewTicker(time.Second) //ticker.C是一个只读的chan,所以直接可以使用for range读取 for v := range ticker.C { fmt.Printf("hello %v\n",v) //按秒输出 } } 一次性定时器 func main() { select { case <- time.After(ti
alexhuiwang
2020/09/24
3970
Go并发编程基础(译)
原文:Fundamentals of concurrent programming 译者:youngsterxyf 本文是一篇并发编程方面的入门文章,以Go语言编写示例代码,内容涵盖: 运行期并发线程(goroutines) 基本的同步技术(管道和锁) Go语言中基本的并发模式 死锁和数据竞争 并行计算 在开始阅读本文之前,你应该知道如何编写简单的Go程序。如果你熟悉的是C/C++、Java或Python之类的语言,那么 Go语言之旅 能提供所有必要的背景知识。也许你还有兴趣读一读 为C++程序员准备的Go
李海彬
2018/03/26
1.5K0
Go并发编程基础(译)
sync.WaitGroup深入源码理解
关于sync.WaitGroup的使用,之前的文章也有介绍,这个文章我就不那么简单的说这个sync.WaitGroup的使用,而是讲讲它的实现原理。
公众号-利志分享
2022/04/25
4080
golang的锁
在Go语言中,锁用于同步访问共享资源。Go语言提供了两种类型的锁:互斥锁(mutex)和读写锁(RWMutex)。
运维开发王义杰
2023/08/21
2350
golang的锁
相关推荐
Go:深入解析internal/race包,数据竞争检测的利器
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验