数据竞争

数据竞争(data race),是多个 goroutine 写一个key 导致数据不一致。
在 golang 中一般使用-race参数检测程序的竞争条件;

举个例子

var n int32
    wg := &sync.WaitGroup{}
    wg.Add(5)
    for i := 0; i < 5; i++ {
        go func() {
            n++
            defer wg.Done()
        }()
    }
    wg.Wait()
    fmt.Println(n)

启动 5 个 goroutine 修改n的值,执行命令
go run -race main.go

==================
WARNING: DATA RACE
Read at 0x00c0000be01c by goroutine 8:
  main.main.func1()
      ... ... 
==================
5
Found 1 data race(s)
exit status 66

找到一个竞争条件,并且已报告行号,接下来尝试第一次修改:

var n int32
    wg := &sync.WaitGroup{}
    mu := sync.Mutex{}
    wg.Add(5)
    for i := 0; i < 5; i++ {
        go func() {
            mu.Lock()
            n++
            defer mu.Unlock()
            defer wg.Done()
        }()
    }
    wg.Wait()
    fmt.Println(n)

增加sync.Mutex的互斥锁,保护变量n,执行 go run -race main.go 结果 5 ,看来起效果了!那有没有其他方式方法呢?
接下来第二次尝试

var n int32
    wg := &sync.WaitGroup{}
    wg.Add(5)
    for i := 0; i < 5; i++ {
        go func() {
            atomic.AddInt32(&n, 1)
            defer wg.Done()
        }()
    }
    wg.Wait()
    fmt.Println(n)

执行go run -race main.go 结果5,看来atomic也可以对变量进行保护。
是否有其他方式?还带模式!

总结

  • 使用 sync.Mutex 保护变量,锁偏重
  • 使用 atomic 保护变量,轻量
相关阅读

https://go.dev/doc/articles/race_detector

最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容