golang中gorace使用

作者:

文章目录
  • 在项目中,使用多线程会导致线程安全问题,引发bug发生,如果是运行中发生问题更难定位 常见的情况有两种 死锁 竞争,例如
  • 虽然说,我们能够通过规范的代码避免死锁,sync.Mutex和channel规避线程安全,但总该有个监测的过程,以防万一 go reac就是帮我们干这个事情的,切记,建议在测试环境中使用!!! 它能帮助你发现程序中是否存在多个 goroutine 同时读写同一个变量而没有同步机制的问题 使用方式例如 go test -race mypkg go run -race mysrc.go go build -race mycmd go install -race mypkg
  • 我们故意写一段,线程危险的程序 package main import ( “fmt” “time” ) var counter int = 0 func main() { go func() { for i := 0; i < 100; i++ { counter++ // 写操作 } }() go func() { for i := 0; i < 100; i++ { counter– // 写操作 } }() time.Sleep(10 * time.Millisecond) // 等待 goroutine 执行(不推荐的方式,仅用于演示) fmt.Println(“Final counter:”, counter) } 使用go run -race main.go调试 这里已经很清晰的将分析报告、代码行数输出 ================== WARNING: DATA RACE Read at 0x000001d6bd90 by goroutine 7: main.main.func2() /Applications/www/blog-code/main.go:19 +0x2c Previous write at 0x000001d6bd90 by goroutine 6: main.main.func1() /Applications/www/blog-code/main.go:13 +0x44 Goroutine 7 (running) created at: main.main() /Applications/www/blog-code/main.go:17 +0x33 Goroutine 6 (finished) created at: main.main() /Applications/www/blog-code/main.go:11 +0x27 ================== ================== WARNING: DATA RACE Read at 0x000001d6bd90 by main goroutine: main.main() /Applications/www/blog-code/main.go:24 +0x77 Previous write at 0x000001d6bd90 by goroutine 7: main.main.func2() /Applications/www/blog-code/main.go:19 +0x44 Goroutine 7 (finished) created at: main.main() /Applications/www/blog-code/main.go:17 +0x33 ================== Final counter: 0 Found 2 data race(s) exit status 66 我们将代码修改一些,加上安全锁 // race_fixed.go package main import ( “fmt” “sync” ) var ( counter int mu sync.Mutex ) func main() { var wg sync.WaitGroup wg.Add(2) go func() { defer wg.Done() for i := 0; i < 100; i++ { mu.Lock() counter++ mu.Unlock() } }() go func() { defer wg.Done() for i := 0; i < 100; i++ { mu.Lock() counter– mu.Unlock() } }() wg.Wait() fmt.Println(“Final counter:”, counter) // 应该输出 0 } 再次执行 go run -race main.go 将没有警告输出 Final counter: 0
  • 不要用于生产环境 -race 会显著降低程序性能(约 2–10 倍变慢),内存占用也更高 windows下需有gcc环境,且与go的版本匹配,例如 go.1.22 使用 gcc version 8.1 会有异常发生,推荐使用 gcc14.2 到此这篇关于golang中go race使用的文章就介绍到这了,更多相关go race使用内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客! 您可能感兴趣的文章: Golang中gRPC内置Trace的实现 浅析Go语言如何避免数据竞争Data Race和竞态条件Race Condition golang beyla采集trace程序原理源码解析 Golang使用pprof和trace进行诊断和修复性能问题 golang trace view视图详解 go如何优雅关闭Graceful Shutdown服务 如何使用golang实现traceroute golang pprof 监控系列 go trace统计原理与使用解析
  • 目录
    • 多线程/协程中的线程安全分析
      • 死锁
      • 竞争
    • Go 的命令中,-race参数用于启用竞态检测器(Race Detector)
      • 使用示例
        • 注意

          在项目中,使用多线程会导致线程安全问题,引发bug发生,如果是运行中发生问题更难定位

          常见的情况有两种 死锁 竞争,例如

          编译打包时,死锁发生 go run 会直接报错

          两个或两个以上的进程(或线程)在执行过程中,因争夺资源而造成的一种相互等待的现象。

          当两个线程竞争同一资源时,如果对资源的访问顺序敏感,就称存在竞态条件。

          虽然说,我们能够通过规范的代码避免死锁,sync.Mutexchannel规避线程安全,但总该有个监测的过程,以防万一

          go reac就是帮我们干这个事情的,切记,建议在测试环境中使用!!!

          它能帮助你发现程序中是否存在多个 goroutine 同时读写同一个变量而没有同步机制的问题

          使用方式例如

          go test -race mypkg    
          go run -race mysrc.go  
          go build -race mycmd   
          go install -race mypkg 
          

          我们故意写一段,线程危险的程序

          package main
          
          import (
          	"fmt"
          	"time"
          )
          
          var counter int = 0
          
          func main() {
          	go func() {
          		for i := 0; i < 100; i++ {
          			counter++ // 写操作
          		}
          	}()
          
          	go func() {
          		for i := 0; i < 100; i++ {
          			counter-- // 写操作
          		}
          	}()
          
          	time.Sleep(10 * time.Millisecond) // 等待 goroutine 执行(不推荐的方式,仅用于演示)
          	fmt.Println("Final counter:", counter)
          }
          

          使用go run -race main.go调试

          这里已经很清晰的将分析报告、代码行数输出

          ==================
          WARNING: DATA RACE
          Read at 0x000001d6bd90 by goroutine 7:
            main.main.func2()
                /Applications/www/blog-code/main.go:19 +0x2c
          
          Previous write at 0x000001d6bd90 by goroutine 6:
            main.main.func1()
                /Applications/www/blog-code/main.go:13 +0x44
          
          Goroutine 7 (running) created at:
            main.main()
                /Applications/www/blog-code/main.go:17 +0x33
          
          Goroutine 6 (finished) created at:
            main.main()
                /Applications/www/blog-code/main.go:11 +0x27
          ==================
          ==================
          WARNING: DATA RACE
          Read at 0x000001d6bd90 by main goroutine:
            main.main()
                /Applications/www/blog-code/main.go:24 +0x77
          
          Previous write at 0x000001d6bd90 by goroutine 7:
            main.main.func2()
                /Applications/www/blog-code/main.go:19 +0x44
          
          Goroutine 7 (finished) created at:
            main.main()
                /Applications/www/blog-code/main.go:17 +0x33
          ==================
          Final counter: 0
          Found 2 data race(s)
          exit status 66
          

          我们将代码修改一些,加上安全锁

          // race_fixed.go
          package main
          
          import (
          	"fmt"
          	"sync"
          )
          
          var (
          	counter int
          	mu      sync.Mutex
          )
          
          func main() {
          	var wg sync.WaitGroup
          	wg.Add(2)
          
          	go func() {
          		defer wg.Done()
          		for i := 0; i < 100; i++ {
          			mu.Lock()
          			counter++
          			mu.Unlock()
          		}
          	}()
          
          	go func() {
          		defer wg.Done()
          		for i := 0; i < 100; i++ {
          			mu.Lock()
          			counter--
          			mu.Unlock()
          		}
          	}()
          
          	wg.Wait()
          	fmt.Println("Final counter:", counter) // 应该输出 0
          }
          

          再次执行 go run -race main.go 将没有警告输出

          Final counter: 0

          1. 不要用于生产环境
          2. -race 会显著降低程序性能(约 2–10 倍变慢),内存占用也更高
          3. windows下需有gcc环境,且与go的版本匹配,例如 go.1.22 使用 gcc version 8.1 会有异常发生,推荐使用 gcc14.2

          到此这篇关于golang中go race使用的文章就介绍到这了,更多相关go race使用内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客!

          您可能感兴趣的文章:

          • Golang中gRPC内置Trace的实现
          • 浅析Go语言如何避免数据竞争Data Race和竞态条件Race Condition
          • golang beyla采集trace程序原理源码解析
          • Golang使用pprof和trace进行诊断和修复性能问题
          • golang trace view视图详解
          • go如何优雅关闭Graceful Shutdown服务
          • 如何使用golang实现traceroute
          • golang pprof 监控系列 go trace统计原理与使用解析

          站内搜索