Golang - 为什么会出现这种竞争状况?

时间:2015-05-09 06:39:40

标签: concurrency go race-condition goroutine

package main
import "fmt"

var quit chan int
var glo int

func test() {
    fmt.Println(glo)
}

func main() {
    glo = 0
    n := 10000
    quit = make(chan int, n)
    go test()
    for {
        quit <- 1
        glo++
    }
}

情况:

上面的程序输出10000.但是当我为 n (例如n := 1000000)分配一个更大的数字时,输出将是一个随机数小于n

我没有调用runtime.GOMAXPROCS(),所以这两个goroutine不能并行运行。执行go run -race以检测竞争条件,结束而不任何警告。

问题:

为什么会出现这种竞争条件?

1 个答案:

答案 0 :(得分:2)

由于maintest goroutines之间没有同步,因此您不知道fmt.Println中的test电话将在何时发生。

使用GOMAXPROCS = 1运行时,答案主要取决于调度程序何时决定停止执行main并切换到test。循环中的发送操作是调度程序可以切换到另一个goroutine的一个点,因此,循环的足够迭代,您希望test有机会在某个时刻执行。每次运行都不一定会在同一次迭代中切换,从而导致结果的变化。

至于用竞赛探测器捕获它,它成功地解决了我的问题:

$ go run -race test.go
==================
WARNING: DATA RACE
Read by goroutine 5:
  main.test()
      /../test.go:8 +0x6e

Previous write by main goroutine:
  main.main()
      /.../test.go:18 +0xfe

Goroutine 5 (running) created at:
  main.main()
      /.../test.go:15 +0x8f
==================
...