【发布时间】:2015-09-17 13:59:30
【问题描述】:
我无法解释比赛检测器中println 和fmt.Println 的不同输出。我预计两者都是种族,或者至少两者都不是种族。
package main
var a int
func f() {
a = 1
}
func main() {
go f()
println(a)
}
而且,它会按预期找到竞争条件。
0
==================
WARNING: DATA RACE
Write by goroutine 5:
main.f()
/home/felmas/test.go:6 +0x30
Previous read by main goroutine:
main.main()
/home/felmas/test.go:11 +0x4d
Goroutine 5 (running) created at:
main.main()
/home/felmas/test.go:10 +0x38
==================
Found 1 data race(s)
但是,这个运行时没有检测到任何种族。
package main
import "fmt"
var a int
func f() {
a = 1
}
func main() {
go f()
fmt.Println(a)
}
据我所知,没有检测到种族并不意味着没有种族,所以这是这些缺陷之一还是有更深层次的解释,因为println 是内置的并且非常特别?
【问题讨论】:
-
这只是偶然。比赛检测器没有看到比赛是 f() 没有执行。
-
@JimB 如果我添加
time.Sleep等待,仍然没有比赛并且输出为1 所以f运行。 -
我明白了。尽管您的测试不正确(并且 sleep 并不能保证 goroutine 会运行),但将值复制到接口中似乎有这种奇怪的行为。 (顺便说一句,比赛检测器只能保证没有误报,所以它偶尔会漏掉一些东西)
-
@JimB 你所说的睡眠是正确的,但在这里看到结果就足够了。我已经怀疑您对副本的解释,但想确保并看到正确的答案,以便我可以学到新的东西。误报,是的,最好检查种族,但我们不能承认没有种族。
-
在此归档以供参考:golang.org/issue/12664
标签: go concurrency goroutine