是什么导致了这种数据竞争?

为什么这段代码会导致数据竞争?我已经使用了原子添加。


package main


import (

    "sync/atomic"

    "time"

)


var a int64


func main() {

    for {

        if a < 100 {

            atomic.AddInt64(&a, 1)

            go run()

        }

    }

}


func run() {

    <-time.After(5 * time.Second)

    atomic.AddInt64(&a, -1)

}

我go run --race用这段代码运行命令并得到:


==================

WARNING: DATA RACE

Write at 0x000001150f30 by goroutine 8:

  sync/atomic.AddInt64()

      /usr/local/Cellar/go/1.11.2/libexec/src/runtime/race_amd64.s:276 +0xb

  main.run()

      /Users/flask/test.go:22 +0x6d


Previous read at 0x000001150f30 by main goroutine:

  main.main()

      /Users/flask/test.go:12 +0x3a


Goroutine 8 (running) created at:

  main.main()

      /Users/flask/test.go:15 +0x75

==================

你能帮我解释一下吗?以及如何解决此警告?谢谢!


阿波罗的战车
浏览 106回答 1
1回答

胡子哥哥

您没有在访问变量的所有atomic地方都使用该包。所有访问都必须同步到从多个 goroutines 同时访问的变量,包括读取:for {&nbsp; &nbsp; if value := atomic.LoadInt64(&a); value < 100 {&nbsp; &nbsp; &nbsp; &nbsp; atomic.AddInt64(&a, 1)&nbsp; &nbsp; &nbsp; &nbsp; go run()&nbsp; &nbsp; }}随着这种变化,竞争条件消失了。如果你只是想检查这个值,你甚至不需要将它存储在一个变量中,所以你可以简单地做:for {&nbsp; &nbsp; if atomic.LoadInt64(&a) < 100 {&nbsp; &nbsp; &nbsp; &nbsp; atomic.AddInt64(&a, 1)&nbsp; &nbsp; &nbsp; &nbsp; go run()&nbsp; &nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go