鉴于下面的代码,我试图理解为什么 Go 竞争检测器 ( go run -race example.go) 不会抱怨竞争条件。
var count int
func main() {
    http.HandleFunc("/a/", func(w http.ResponseWriter, r *http.Request) {
        count++ 
        fmt.Println(count)
    })
    http.HandleFunc("/b/", func(w http.ResponseWriter, r *http.Request) {
        count++
        fmt.Println(count)
    })
    log.Fatal(http.ListenAndServe(":8080", nil))
}
我的理解是 Go HTTP Server 在一个单独的 goroutine 中响应所有请求。考虑到这一点,处理函数对全局计数变量的增量是否会发生在与主 goroutine 分开的 goroutine 中,从而构成数据竞争?
如果这不是数据竞赛,我非常想知道原因。
这是一个竞争条件。种族检查器可能会出现误报。
竞争检查器是动态的:它不会检查源是否存在问题,而是只能查看读取和写入是否实际发生,而中间没有同步操作。您的代码中没有同步操作,但如果在net/http增量之间发生同步操作,它就会被愚弄。  它的作者建议,本质上,运行并发压力测试来解决问题:
- 编写良好的并发测试
- 使用竞赛检测器进行连续构建
- 运行集成测试
- 在生产环境中运行支持竞赛的金丝雀
在 Go 1.4 及更低版本中,您还应该确保您的程序在多个内核上运行,例如runtime.GOMAXPROCS(runtime.NumCPU()). 在将于 2015 年底发布的 Go 1.5 中,GOMAXPROCS 默认将在所有可用内核上运行您的代码。