go - 如何修复 "one problem on race condition check which using go-build-race tools"?

标签 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)

这是两个不同的结果。

最佳答案

我建议你探索 go 中的调度(来自 ardanlabs 的好文章)。

简单的回答是你无法控制执行顺序,Go运行时可以控制。同一程序的每次执行不会产生相同的执行跟踪。 Race detector跟踪每次运行的“活泼”行为,结果直接取决于调度程序的决定。

关于go - 如何修复 "one problem on race condition check which using go-build-race tools"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54249493/

相关文章:

python - sqlalchemy 中的并发

perl - 使用 alarm 设置读取 stdin 的超时时间

ios - coreData executeFetchRequest 方法的竞争条件导致 nil 数据的问题

c - glDisplayFunc(RenderScene) 回调是否会在以下代码中导致竞争条件?

go - 为什么不使用 go-pkg-rss 返回 Atom 项目标题?

amazon-web-services - 是否有用于读取文件而不是下载文件的 AWS S3 Go API?

regex - 使用正则表达式替换 Go 中的文本

sql - 是否可以为多个请求准备一次 SQL 语句?

java - Replicated Workers 范例中更多线程的随机结果

java - Java 中是否有快速失败的同步方式?