简体   繁体   English

是什么导致此数据竞赛?

[英]What is causing this data race?

Why does this code cause data race? 为什么此代码会引起数据争用? I have already used atomic add. 我已经使用了原子添加。

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)
}

I run command go run --race with this code and get: 我使用以下代码运行命令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
==================

Could you help me explain this? 你能帮我解释一下吗? And how to fix this warning? 以及如何解决此警告? Thanks! 谢谢!

You didn't use the atomic package at all places where you accessed the variable. 您没有在访问变量的所有位置使用atomic包。 All access must be synchronized to variables that are accessed from multiple goroutines concurrently, including reads : 所有访问必须同步到同时从多个goroutine访问的变量,包括reads

for {
    if value := atomic.LoadInt64(&a); value < 100 {
        atomic.AddInt64(&a, 1)
        go run()
    }
}

With that change, the race condition goes away. 有了这种改变,比赛条件就消失了。

If you just want to inspect the value, you don't even need to store it in a variable, so you may simply do: 如果您只想检查该值,则甚至不需要将其存储在变量中,因此您可以简单地执行以下操作:

for {
    if atomic.LoadInt64(&a) < 100 {
        atomic.AddInt64(&a, 1)
        go run()
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM