【发布时间】:2019-05-23 11:19:53
【问题描述】:
我正在学习 Golang 中与并发相关的问题。我写了一些代码:
package main
import (
"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 lock 来解决这个问题。
代码在 Playground 中可用:https://play.golang.org/p/Tba9pfpxaHY
你能解释一下这个程序到底发生了什么吗?
【问题讨论】:
-
它不起作用。你刚刚得到了“幸运”。也许您正在单 CPU 机器上运行(例如 Go 游乐场)?使用竞赛检测器 (
go run -race) 运行它。 -
IMO,这就是为什么并发编程更难的原因 :) 没有明显的错误或恐慌,可以在观察下工作。虽然竞态检测器极有可能检测到这种特定的竞态条件,但在某些条件/情况下,竞态检测器不会检测到任何东西。这就是 IMO 我们仍然需要回归第一原则并学习识别所有并发访问 (medium.com/dm03514-tech-blog/…) 并默认保护的地方
标签: go concurrency locking mutex shared-memory