Search code examples
go

Golang race condition example with a map (does it matter?)


Go web-site page about race conditions:

https://go.dev/doc/articles/race_detector

gives an example of a program with a race condition, I am Posting the source here:

package main

import "fmt"

func main() {
    c := make(chan bool)
    m := make(map[string]string)
    go func() {
        m["1"] = "a"
        c <- true
    }()
    m["2"] = "b"
    <-c
    for k, v := range m {
        fmt.Println(k, v)
    }
}

Does the fact that multiple map write accesses are not thread-safe in Go make this code unreliable? Empirically I run it 300 times on my system and I do not get any issues, only that the Elements are added and printed in different order, but so what, how is that an issue for a map?


Solution

  • This is an issue because operations that mutate a map are not synchronised. In the example code, the main goroutine and the explicit goroutine both update the map, potentially simultanouesly.

    Two goroutines simultaneously updating a map could corrupt the map state, resulting in unexpected behaviour.

    This is assumed knowledge on the web page you reference (strictly speaking, it is described in the Go Memory Model documentation referenced on that page, but not so directly).

    The additional link provided by Cerise clarifies that [for maps] this was a deliberate design decision on the part of the language and is not a "bug". In short, synchronising map writes would introduce overhead to these operations, which would be unnecessary in (what are believe to be) the overwhelming majority of cases. Where write operations to a shared map must be synchronised, this must be explicitly implemented or a lock-free map (sync.Map) used.

    Why You Don't See Problems When Running The Code

    Problems are not guaranteed to occur in any particular code execution; other factors could avoid synchronisation problems or result in coincidental synchronisation. However, this synchronisation is not built into the map type and must not be relied upon.