猿问

为什么共享 int 变量在 go 例程中递增时显示原子行为?

当我运行下面的代码片段时,它看起来总是打印值 20000000。当我创建更多 go 例程以在没有锁定的情况下递增计数器时,它显示出类似的行为。但是不应该存在某种竞争条件吗?谢谢 !


package main


import "fmt"


const (

N_INCREMENTS = 10000000

)


func main() {


var counter int = 0

donechan := make(chan bool)


go func(done chan<- bool) {

    for i := 0; i < N_INCREMENTS; i++ {

        counter++

    }

    done <- true

}(donechan)


for i := 0; i < N_INCREMENTS; i++ {

    counter++

}


_ = <-donechan


fmt.Println("Count: ", counter)

}


慕田峪4524236
浏览 160回答 1
1回答

饮歌长啸

runtime.GOMAXPROCS(0)将报告可以并行运行的 goroutine 的数量。如果值为 1,您可能不会观察到不同步counter变量的任何“副作用” 。如果首先在程序开始时将其设置为2:runtime.GOMAXPROCS(2)您将立即看到效果:Count:&nbsp; 10319575如果您想获得竞争条件的证明,请提供-race参数。输出-race:==================WARNING: DATA RACERead by goroutine 6:&nbsp; main.main.func1()&nbsp; &nbsp; &nbsp; V:/workspace/IczaGo/src/play/play.go:20 +0x48Previous write by main goroutine:&nbsp; main.main()&nbsp; &nbsp; &nbsp; V:/workspace/IczaGo/src/play/play.go:26 +0xefGoroutine 6 (running) created at:&nbsp; main.main()&nbsp; &nbsp; &nbsp; V:/workspace/IczaGo/src/play/play.go:23 +0xbc==================(请注意,竞争检测器仅适用于 64 位 Go 发行版。)在 Go 操场上,1默认情况下是 GOMAXPROCS 。此行将打印前一个值并将其设置为2:fmt.Println("Previous GOMAXPROCS:", runtime.GOMAXPROCS(2))输出(在Go Playground上试试):Previous GOMAXPROCS: 1Count:&nbsp; 12844130另请注意,GOMAXPROCS1在 1.5 之前的 Go 发行版中设置为。从 1.5 开始,GOMAXPROCS 的默认值是运行程序的机器上可用的 CPU 内核数。
随时随地看视频慕课网APP

相关分类

Go
我要回答