from Hacker News

Are Go maps sensitive to data races?

by spacey on 12/7/15, 10:57 AM with 79 comments

  • by alkonaut on 12/7/15, 11:45 AM

    Any data structure that isn't explicitly designed for concurrent access will not work when used concurrently.

    Since a concurrent map (aka. Dictionary aka. Hashtable) is a lot more complex and slow than a non concurrent one, it's very very unlikely that Go would ship with its standard map type being a concurrent one. It would be a huge waste.

    More likely there is a separate concurrent map type. It's exactly the same in other languages with mutable collections (Java, .NET, C++, ...).

  • by JulianMorrison on 12/7/15, 12:19 PM

    The other reason: things inside maps are often pointer types with mutable data. Even if access to the map is properly locked, if two threads take a pointer out of it and directly or indirectly keep a reference (for example, re-slicing a slice without copying it), then one can stomp on the data the other is reading.

    The fixes for this are subtle and annoying. Either you have to lock around your data, make it somehow immutable, or force copying rather than referencing (by making it "value" data).

    Go would really benefit from a port of Clojure's data structures.

  • by kasey_junk on 12/7/15, 11:57 AM

    A concurrent map is the top of my wants list for go by a long stretch. The next thing on that list is a high performance concurrent queue. That these things aren't available is a direct result of the decision to not support user defined generics in go.
  • by zalmoxes on 12/7/15, 12:24 PM

  • by grabcocque on 12/7/15, 11:26 AM

    "no, there is nothing wrong with Go’s map implementation."

    "Getting your locking wrong will corrupt the internal structure of the map."

    Ahem.

    If you have a non-concurrency-safe map implementation in a language that's advertised as being good for concurrency, there is definitely something wrong.

  • by khgvljhkb on 12/7/15, 12:37 PM

    Golang devs should have a look at Clojure and it's `core.async` library. It works very similarly to Go (heavily inspired by the good stuff), but all data structures are persistent, meaning you will never have problems with concurrent mutations (because there there are no mutations in the API, only internally).

    I recommend Go users to install the boot utility, and playing around with Clojure & core.async. These communities can share many things.

  • by SixSigma on 12/7/15, 12:36 PM

    Share memory by communicating; don't communicate by sharing memory.

    https://golang.org/doc/codewalk/sharemem/

  • by vinceyuan on 12/7/15, 12:40 PM

    > Go maps are not goroutine safe

    Which types in Go are goroutine safe? Do we need to use sync.Mutex for all global variables which are read and written in goroutines? My understanding is only read-only variables are goroutine safe.