Go race数据竞争检测
对同一内存的竞争读写,会导致出现数据错乱,是多进程/线程编码中的常见问题。
go中提供了race工具协助识别代码中的数据竞争问题。使用起来也非常方便,设计编译的操作时加上-race即可:
go test -race xxx
go run -race xxx
go build -race xxx
go install -race xxx
这样编译出来的二进制在执行时如果检测到竞争,就可以输出报告。
还可以通过GORACE环境变量来控制race的一些行为,比如输出报告的路径,检测到报告是否退出等。
举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | package main import "time" func myChan() { ch1 := make( chan int, 1) go func () { ch1 <- 123 }() time.Sleep(1 * time.Second) close(ch1) } func main() { myChan() } |
执行输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | zxq@DESKTOP-0BAPSTC: /mnt/d/go_test $ go run -race go_testrace.go ================== WARNING: DATA RACE Write at 0x00c000122010 by main goroutine: runtime.closechan() /usr/local/go/src/runtime/chan .go:357 +0x0 main.myChan() /mnt/d/go_test/go_testrace .go:13 +0x84 main.main() /mnt/d/go_test/go_testrace .go:17 +0x2f Previous read at 0x00c000122010 by goroutine 6: runtime.chansend() /usr/local/go/src/runtime/chan .go:158 +0x0 main.myChan.func1() /mnt/d/go_test/go_testrace .go:9 +0x4b Goroutine 6 (finished) created at: main.myChan() /mnt/d/go_test/go_testrace .go:8 +0x69 main.main() /mnt/d/go_test/go_testrace .go:17 +0x2f ================== Found 1 data race(s) exit status 66 |
从代码可以看出,执行过程本身是不会竞争的(sleep错开了时间),但是程序检测到了这个风险。
race检测的特点:
1.运行时检测,不是静态代码检查。
2.只有执行到的代码才能被检查出来竞争。比如一些if else的代码分支没走到,就不会检测到其中可能存在的竞争。
3.只要代码执行到就能检测出来,即使不一定出现竞争。比如上面的例子,一般是不会出现竞争态的。
4.会严重影响程序性能,可能会占用数倍的cpu和内存。所以正式环境不能上线。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具