为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
慕田峪4524236 2021-11-22 15:59:00
当我运行下面的代码片段时,它看起来总是打印值 20000000。当我创建更多 go 例程以在没有锁定的情况下递增计数器时,它显示出类似的行为。但是不应该存在某种竞争条件吗?谢谢 !package mainimport "fmt"const (N_INCREMENTS = 10000000)func main() {var counter int = 0donechan := 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++}_ = <-donechanfmt.Println("Count: ", counter)}
查看完整描述

1 回答

?
饮歌长啸

TA贡献1951条经验 获得超3个赞

runtime.GOMAXPROCS(0)将报告可以并行运行的 goroutine 的数量。如果值为 1,您可能不会观察到不同步counter变量的任何“副作用” 。


如果首先在程序开始时将其设置为2:


runtime.GOMAXPROCS(2)

您将立即看到效果:


Count:  10319575

如果您想获得竞争条件的证明,请提供-race参数。输出-race:


==================

WARNING: DATA RACE

Read by goroutine 6:

  main.main.func1()

      V:/workspace/IczaGo/src/play/play.go:20 +0x48


Previous write by main goroutine:

  main.main()

      V:/workspace/IczaGo/src/play/play.go:26 +0xef


Goroutine 6 (running) created at:

  main.main()

      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: 1

Count:  12844130

另请注意,GOMAXPROCS1在 1.5 之前的 Go 发行版中设置为。从 1.5 开始,GOMAXPROCS 的默认值是运行程序的机器上可用的 CPU 内核数。


查看完整回答
反对 回复 2021-11-22
  • 1 回答
  • 0 关注
  • 149 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信