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

Golang 并发写入变量 - 为什么这段代码有效?

Golang 并发写入变量 - 为什么这段代码有效?

Go
GCT1015 2023-06-19 16:01:07
我正在学习 Golang 中与并发相关的问题。我写了一些代码:package mainimport (    "fmt"    "time")func incr(num *int) {    *num = *num + 1}func main() {    var a = 0    for i := 0; i < 50; i++ {        go incr(&a)    }    incr(&a)    time.Sleep(1 * time.Second)    fmt.Println(a)}这段代码的结果是:51在这段代码中,我声明了a在 50 个正在运行的 goroutine 中增加的变量。根据我的阅读和理解,这段代码应该会失败,因为多个 goroutine 正在写入相同的内存地址。在这种情况下,我应该添加sync.Mutex锁来解决这个问题。代码在操场上可用:https ://play.golang.org/p/Tba9pfpxaHY您能解释一下这个程序中到底发生了什么吗?
查看完整描述

1 回答

?
心有法竹

TA贡献1866条经验 获得超5个赞

你猜怎么了?我运行了您的应用程序,得到了不同的输出:有时,49,有时,有时(有时)。485051


如果您在启用竞争检测器 ( go run -race play.go) 的情况下运行您的应用程序,它会告诉您存在数据竞争:


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

WARNING: DATA RACE

Read at 0x00c00009a010 by goroutine 7:

  main.incr()

      /home/icza/gows/src/play/play.go:9 +0x3a


Previous write at 0x00c00009a010 by goroutine 6:

  main.incr()

      /home/icza/gows/src/play/play.go:9 +0x50


Goroutine 7 (running) created at:

  main.main()

      /home/icza/gows/src/play/play.go:17 +0x83


Goroutine 6 (finished) created at:

  main.main()

      /home/icza/gows/src/play/play.go:17 +0x83

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

当你有数据竞争时,你的应用程序的行为是未定义的。“看似有时工作”也符合“未定义”行为,但未定义也意味着它也可以做任何其他事情。


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

添加回答

举报

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