如何解决“使用go-build-race工具检查种族状况的一个问题”?

时间:2019-01-18 07:32:22

标签: go concurrency race-condition

首先,我知道代码具有一定的竞争条件,因此我使用“ go build -race”命令进行了检查,我想看看结果如何显示,在我第一次运行时,它显示了一个结果如下,然后再次运行显示第二个结果,它有两个不同的结果,我不知道为什么,有谁能告诉我原因,以及代码是如何执行的?,非常感谢许多。

源代码:

package main

import (
    "fmt"
    "runtime"
    "sync"
)

var (
    counter int
    wg sync.WaitGroup
)

func main() {
    wg.Add(2)

    go incCounter(1)
    go incCounter(2)

    wg.Wait()

    fmt.Println("Final Counter:", counter)

}

func incCounter(id int) {
    defer wg.Done()

    for count := 0; count < 2; count++ {
        value := counter
        // switch goroutine
        runtime.Gosched()
        value++
        counter = value
    }
}

当我使用go build -race工具检查比赛条件时,它显示两个不同的结果,如下所示:

一个结果:

==================
WARNING: DATA RACE
Write at 0x0000005fb2d0 by goroutine 7:
  main.incCounter()
      D:/Go/projects/hello-world/src/concurrency/list7/m.go:34 +0x97

Previous read at 0x0000005fb2d0 by goroutine 6:
  main.incCounter()
      D:/Go/projects/hello-world/src/concurrency/list7/m.go:30 +0x76

Goroutine 7 (running) created at:
  main.main()
      D:/Go/projects/hello-world/src/concurrency/list7/m.go:18 +0x90

Goroutine 6 (running) created at:
  main.main()
      D:/Go/projects/hello-world/src/concurrency/list7/m.go:17 +0x6f
==================
==================
WARNING: DATA RACE
Write at 0x0000005fb2d0 by goroutine 6:
  main.incCounter()
      D:/Go/projects/hello-world/src/concurrency/list7/m.go:34 +0x97

Previous write at 0x0000005fb2d0 by goroutine 7:
  main.incCounter()
      D:/Go/projects/hello-world/src/concurrency/list7/m.go:34 +0x97

Goroutine 6 (running) created at:
  main.main()
      D:/Go/projects/hello-world/src/concurrency/list7/m.go:17 +0x6f

Goroutine 7 (running) created at:
  main.main()
      D:/Go/projects/hello-world/src/concurrency/list7/m.go:18 +0x90
==================
Final Counter: 2
Found 2 data race(s)

第二结果:

==================
WARNING: DATA RACE
Read at 0x0000005fb2d0 by goroutine 7:
  main.incCounter()
      D:/Go/projects/hello-world/src/concurrency/list7/m.go:30 +0x76

Previous write at 0x0000005fb2d0 by goroutine 6:
  main.incCounter()
      D:/Go/projects/hello-world/src/concurrency/list7/m.go:34 +0x97

Goroutine 7 (running) created at:
  main.main()
      D:/Go/projects/hello-world/src/concurrency/list7/m.go:18 +0x90

Goroutine 6 (finished) created at:
  main.main()
      D:/Go/projects/hello-world/src/concurrency/list7/m.go:17 +0x6f
==================
Final Counter: 4
Found 1 data race(s)

它们是两个不同的结果。

1 个答案:

答案 0 :(得分:2)

我建议您边走边探索计划安排(ardanlabs的好文章)。

简短的答案是,您不控制执行顺序,而运行时则可以。相同程序的每次执行都不会产生相同的执行跟踪。 Race detector跟踪每次运行中的“恶意”行为,结果直接取决于调度程序的决定。