用于println和fmt.Println

时间:2015-09-17 13:59:30

标签: go concurrency goroutine

我在竞赛检测器中有printlnfmt.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内置且非常特殊而有更深层次的解释?

1 个答案:

答案 0 :(得分:0)

竞赛探测器是一种动态测试工具,没有静态分析。为了从竞赛检测器获得可靠的结果,您应该争取高度测试程序,最好是使用多个进程编写大量benchmarks(通过设置GOMAXPROCS> 1,GOMAXPROCS = NumCPU是默认值对于Go 1.5)并使用持续集成工具定期执行这些测试。

竞赛检测器不报告任何误报,因此您应该认真对待每一个输​​出。另一方面,根据订单goroutines和进程的安排,它可能无法检测每次运行中的每场比赛。

在您的示例中,在紧密循环中包装所有内容并重新执行测试会在两种情况下正确报告竞争。