猿问

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

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以检测竞争条件,最终没有任何警告。


题:


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


绝地无双
浏览 183回答 1
1回答

慕的地6264312

由于goroutinesmain和testgoroutines之间没有同步,你不知道fmt.Println调用 intest会在什么时候发生。运行时GOMAXPROCS = 1,答案主要取决于调度程序何时决定停止执行main并切换到test。循环中的发送操作是调度程序可以切换到另一个 goroutine 的一个点,因此通过足够的循环迭代,您希望test有机会在某个时刻执行。不一定每次运行都在相同的迭代中进行切换,从而导致结果的变化。至于用比赛检测器捕捉到这个,它成功地为我解决了这个问题:$ go run -race test.go==================WARNING: DATA RACERead by goroutine 5:&nbsp; main.test()&nbsp; &nbsp; &nbsp; /../test.go:8 +0x6ePrevious write by main goroutine:&nbsp; main.main()&nbsp; &nbsp; &nbsp; /.../test.go:18 +0xfeGoroutine 5 (running) created at:&nbsp; main.main()&nbsp; &nbsp; &nbsp; /.../test.go:15 +0x8f==================...
随时随地看视频慕课网APP

相关分类

Go
我要回答