A Simple Race Condition in the Go HTTP Handler - Is It Really A Race Condition?

Given the code below, I'm trying to figure out WHY the Go ( go run -race example.go

) race detector is not complaining about a race condition.

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))
}

      

I understand that the Go HTTP server responds to all requests in a separate goroutine. With this in mind, wouldn't the increments made to the global counter by handler functions happen in a goroutine that is separate from the main goroutine and thus constitute a data race?

If this is not a data race, I'd really like to know why.

+3


source to share


3 answers


This is a data race, however the race detector does not report races that do not exist. You need to make sure there are concurrent calls in your test, and provisioning GOMAXPROCS>1

can help clean those up as well.



+4


source


This is a race condition. False negatives can happen with race checks.

The race controller is dynamic: instead of checking the source of the problem, it can only see if there are actually reads and writes, without synchronization between them. There is no synchronization operation in your code, but if net/http

it occurs in the increments between increments, it will be fooled. Its author suggests essentially parallel stress tests to get rid of the problems:



  • write good parallel tests
  • have a continuous assembly with a race detector
  • run integration tests
  • launch rockets with included canaries into production

In Go 1.4 and below, you must also ensure that your program runs on multiple cores, for example runtime.GOMAXPROCS(runtime.NumCPU())

. In Go 1.5, which will be released in late 2015, GOMAXPROCS will run your code on all available kernels by default.

+4


source


count++

- data race. It doesn't happen atomically. This is the same as:

count = count + 1

      

If the race detector doesn't see this, you are probably not hitting the server hard enough.

+3


source







All Articles