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

围棋比赛条件改变

围棋比赛条件改变

Go
泛舟湖上清波郎朗 2021-04-09 19:15:59
《 Go in action》关于比赛条件的样本:var (    counter int    wg sync.WaitGroup)func main() {    wg.Add(2)    go incCounter(1)    go incCounter(2)    wg.Wait()    fmt.Println("Final Counter:", counter)}func incCounter(id int) {    defer wg.Done()    for count := 0; count < 2; count++ {        value := counter        //1 fmt.Println("value=",value)        runtime.Gosched()        value++        counter = value        //2 fmt.Println("counter=",counter)    }}据说最终计数器的末尾应为2,解释如下:“每个goroutine都会覆盖另一个工作。这在goroutine交换发生时会发生。每个goroutine都会制作自己的counter变量副本,然后进行交换当该goroutine有时间再次执行时,counter变量的值已更改,但goroutine不会更新其副本,而是继续增加其拥有的副本并将其值重新设置为计数器变量,替换了其他goroutine执行的工作。”我想这是环境原因,我的机器输出4为1.10.3 + win10。我想知道自本书发行以来发生了什么变化?如果我取消注释1,则最终计数器将打印2;如果我取消注释2,则将随机打印2。为什么?
查看完整描述

1 回答

?
长风秋雁

TA贡献1757条经验 获得超7个赞

这本书是错的。关于数据争用的要点是结果不确定。


例如,Final Counter可以是任何值。


package main


import (

    "fmt"

    "runtime"

    "sync"

)


var (

    counter int

    wg      sync.WaitGroup

)


func main() {

    wg.Add(2)

    go incCounter(1)

    go incCounter(2)


    wg.Wait()

    fmt.Println("Final Counter:", counter)

}


func incCounter(id int) {

    defer wg.Done()


    for count := 0; count < 2; count++ {

        value := counter

        //1 fmt.Println("value=",value)

        runtime.Gosched()


        value++


        counter = value

        //2 fmt.Println("counter=",counter)

    }

}

输出:


$ go version

go version devel +65fa2b615b Fri Aug 3 23:35:53 2018 +0000 linux/amd64

$ go run racer.go

Final Counter: 4

$ go run racer.go

Final Counter: 2

$ go run racer.go

Final Counter: 2

$ go run racer.go

Final Counter: 2

$ go run racer.go

Final Counter: 2

$ go run racer.go

Final Counter: 4

$ go run racer.go

Final Counter: 2

$ go run racer.go

Final Counter: 4

$ go run -race racer.go

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

WARNING: DATA RACE

Read at 0x0000005e4600 by goroutine 7:

  main.incCounter()

      /home/peter/gopath/src/racer.go:27 +0x6f


Previous write at 0x0000005e4600 by goroutine 6:

  main.incCounter()

      /home/peter/gopath/src/racer.go:33 +0x90


Goroutine 7 (running) created at:

  main.main()

      /home/peter/gopath/src/racer.go:17 +0x89


Goroutine 6 (finished) created at:

  main.main()

      /home/peter/gopath/src/racer.go:16 +0x68

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

Final Counter: 4

Found 1 data race(s)

exit status 66

$


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

添加回答

举报

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