-1

Go's map is said not to be goroutine-safe (see here and here). I'm interested at finding out what could happen in a case where I neglect to protect access to the map using mutex/etc.

Specifically, can any of the following happen?

  1. Assuming I have a map with keys k1, k2, ..., kn, can a concurrency issue lead to getting map[ki] when I asked for map[kj] (i != j)?
  2. Can it lead to a panic in the application?
orcaman
  • 6,263
  • 8
  • 54
  • 69
  • 4
    You will corrupt memory. In go 1.6 it will purposely crash the program to prevent unsafe behavior when this is detected. It doesn't matter that a map specifically isn't safe to use concurrently, no values are safe to read and write concurrently in go, ever. – JimB Feb 16 '16 at 11:46
  • 3
    There is really no need to know the answers to your specific questions. Your code is broken. Broken, not "broken but broken in this specific way which is okay in this situation". Just broken. – Volker Feb 16 '16 at 12:02
  • @JimB thanks. Needless to say, I know this, otherwise I would not link to the above mentioned sources. I have actually written this repo to handle it: https://github.com/streamrail/concurrent-map However I was never able to demonstrate this issue, which is why I have asked the above. Any reference to code that will answer my question will be appreciated. – orcaman Feb 16 '16 at 12:10
  • 1
    Even if you find the answers to your questions, those answers may be outdated in the next Go release, or on another platform, or when a different compiler is used... which pretty much renders the information useless... Also possible duplicate of [this](http://stackoverflow.com/questions/34732483/what-happens-if-i-concurrently-access-a-single-go-map) or [this](http://stackoverflow.com/questions/11063473/map-with-concurrent-access). – icza Feb 16 '16 at 13:05
  • The only universal answer is that like with any race condition, anything could happen. Especially with a map, once it's corrupted you can be reading and writing from anywhere in your programs memory. Whenever someone has a "strange runtime bug", it's almost always a data race. – JimB Feb 16 '16 at 13:18

1 Answers1

8

As the comments have already stated, races are bad. Go has very weak guarantees, unlike Java, and hence a program that has any race is allowed to have undefined behavior even when the race-containing code is not executed. In C, this is called "catch-fire semantics". The presence of a race means any outcome is possible, to include your computer catching on fire.

However, in Go it is easy to make a map thread-safe. Consider the following:

// Global variable defining a map
var safemap = struct {
    sync.RWMutex
    m map[string]string
}{m: make(map[string]string)}

You can do safe reads from the map like this:

// Get a read lock, then read from the map
safemap.RLock()
defer safemap.RUnlock()
return safemap.m[mykey] == myval

And you can do safe modifications like this:

// Delete from the map
safemap.Lock()
delete(safemap.m, mykey)
safemap.Unlock()

or this:

// Insert into the map
safemap.Lock()
safemap.m[mykey] = myval
safemap.Unlock()
Mike Spear
  • 832
  • 8
  • 13