Как исправить «одну проблему при проверке состояния гонки с использованием инструментов go-build-race»? - PullRequest
0 голосов
/ 18 января 2019

Сначала я знаю, что в коде есть некоторое состояние гонки, поэтому я использовал команду "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 голосов
/ 18 января 2019

Я предлагаю вам изучить планирование в го (хорошая статья из ardanlabs ).

Короткий ответ: вы не контролируете порядок выполнения, а go runtime делает. Каждое выполнение одной и той же программы не приведет к одному и тому же следу выполнения. Детектор гонки отслеживает "неординарное" поведение при каждом запуске и результаты напрямую зависят от решения планировщика.

...