go - 为什么我的 for 循环只在我放慢速度时才起作用?

标签 go

此代码打印 0,但如果我将 time.Sleep(0) 插入更新程序 循环,它打印 >1

var Nonce int = 0

func Updater(){
    for{
        Nonce += 1
    }
}

func main(){
    go Updater()
    time.Sleep(time.Second)
    fmt.Printf("%d\n",Nonce)
}

最佳答案

nonce.go:

package main

import (
  "fmt"
  "time"
)

var Nonce int = 0

func Updater() {
  for {
      Nonce += 1
  }
}

func main() {
  go Updater()
  time.Sleep(time.Second)
  fmt.Printf("%d\n", Nonce)
}

首先,Go gc 编译器是一个优化编译器。 goroutine 之间没有同步。因此 Nonce += 1 语句被省略,Nonce 的值保持为零。查看编译后的代码:

$ go build nonce.go
$ objdump -d -S ./nonce

输出:

var Nonce int = 0

func Updater() {
    for {
        Nonce += 1
  4888f0:   eb fe                   jmp    4888f0 <main.Updater>
  4888f2:   cc                      int3   
    }
}

其次,如果我们运行 Go 数据竞争检测器,一些优化会被抑制。因此,检测到 Nonce 变量的数据竞争条件。数据竞争的结果是不确定的。

$ go run -race nonce.go
==================
WARNING: DATA RACE
Read at 0x0000005f2648 by main goroutine:
  main.main()
      /home/peter/gopath/src/nonce.go:19 +0x63

Previous write at 0x0000005f2648 by goroutine 6:
  main.Updater()
      /home/peter/gopath/src/nonce.go:12 +0x56

Goroutine 6 (running) created at:
  main.main()
      /home/peter/gopath/src/nonce.go:17 +0x46
==================
42758109
Found 1 data race(s)
exit status 66
$  

关于go - 为什么我的 for 循环只在我放慢速度时才起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54578762/

相关文章:

mysql - select query MySQL, Beego 中如何选择特定id的总和

go - 如何部署 travis 自动构建,我的失败了,我不知道如何修复

go - 使用 header 作为 application/json 在 Golang 中获取 POST 参数

go - 单元测试时如何包含go模板

将一个简单的哈希函数从 c 转换为 go

parsing - 如果没有换行符,如何从 reader.ReadString 获取最后一行

datetime - 将 UTC 字符串转换为时间对象

go - 在 mac OS Sierra 10.12 上安装 gomobile

Go,是否可以将 defer 放在子函数中

user-interface - 如何在 go winc gui windows 库 OnDropFiles 事件中获取文件名