-2

You can consider this example:

package maptest

var oldMap = map[string]string{"key1": "old_value1", "key2": "old_value2", "key3": "old_value3"}

func updateMap() {
    oldMap = map[string]string{"key1": "new_value1", "key2": "new_value2", "key3": "new_value3"}

}

func action1() string {
    return oldMap["key1"]
}

func action2() {
    var resultKey string
    var resultValue string

    for k, v := range oldMap {
        resultKey += oldMap[k]
        resultValue += v
    }
}
  1. if the updateMap() function is executed in parallel with action1(), will it cause a panic or will action1() just return the old value? Why?
  2. if the updateMap function is executed while the action2() cycle is running, what will be the result? I'm assuming that getting by key will start accessing the new map, while v will belong to a copy of the old one. Is it so? Is the variant with v safe in this case and guarantees the correct result (data from one map)?
ragarac3
  • 51
  • 2
  • 2
    No value is safe for concurrent access where at least one of the accesses is a write. `updateMap()` writes `oldMap`, and `action1()` and `action2()` are reading it. It's a data race. – icza May 18 '23 at 18:59
  • 1
    For the second part, also see [Concurrent access to maps with 'range' in Go](https://stackoverflow.com/questions/40442846/concurrent-access-to-maps-with-range-in-go/40456170#40456170) – icza May 18 '23 at 19:02

1 Answers1

0

There's nothing special about package-level variables when we're talking about manipulating them by the code which runs starting with the first statement of the function main of package main. There do exist special rules regarding order in which package-level variables get initialized but once the "normal" program flow starts, these variables are just regular locations in RAM with no special semantics.

This means, any concurrent map access at least one of which is writing–this includes adding new entries to a map, updating existing entries and deleting entries–is a data race and is undefined behavior in Go. Concurrent access to a variable containing a map (not the map itself referenced by that variable) is bound by the same rules: if at least one of these concurrent accesses is a write, this is a data race and is undefined behavior in Go.

kostix
  • 51,517
  • 14
  • 93
  • 176