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
以检测竞争条件,结束而不任何警告。
问题:
为什么会出现这种竞争条件?
答案 0 :(得分:2)
由于main
和test
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
==================
...