douruhu4282
2019-01-08 11:02
浏览 100
已采纳

是什么导致此数据竞赛?

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:

==================
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!

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • duankangzi766767 2019-01-08 11:07
    已采纳

    You didn't use the atomic package at all places where you accessed the variable. All access must be synchronized to variables that are accessed from multiple goroutines concurrently, including 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()
        }
    }
    
    已采纳该答案
    打赏 评论

相关推荐 更多相似问题