问题描述:

In my project I need to read a value as a global variable so I am using maps (global variable)

var url = make(map[string]string)

and I occasionally get into error "Concurrent writes" as I assign value in a function (cant assign global as it gives an error non-declarative statement).

url["test"] = "http://google.com"

In PHP I could easily do this through an multidimensioanl array and read the value. Is there a way I could just use multidimensional array or maps in Go to just assign and read it in a function?

Any help is appreciated.

网友答案:

The Concurrent writes error happens when the Go runtime detects concurrent writes to the map by different goroutines. It is a feature added in go1.6:

https://blog.golang.org/go1.6

The runtime has added lightweight, best-effort detection of concurrent misuse of maps. As always, if one goroutine is writing to a map, no other goroutine should be reading or writing the map concurrently. If the runtime detects this condition, it prints a diagnosis and crashes the program. The best way to find out more about the problem is to run it under the race detector, which will more reliably identify the race and give more detail.

You can initialize a map on a global level - see https://play.golang.org/p/AjqtQBGMEM (or below) for an example. The same code snippet shows how maps data races can be prevented with synchronisation mechanisms - use a mutex, lock before writing to a map, and unlock afterwards.

    package main

    import (
        "fmt"
        "sync"
    )

    var mu sync.Mutex
    var mymap = map[string]string{"hello": "world", "foo": "bar"}

    func main() {
        demo()
    }

    func demo() {
        mu.Lock()
        defer mu.Unlock()
        mymap["hello"] = "gophers"
        fmt.Println("hello, ", mymap["hello"])  
    }

Another way to avoid the data race is to use a channel of size 1 (non-buffered), similar to the Tour example in https://tour.golang.org/concurrency/2: extract the map from the channel, write to it, and put it back to the channel.

https://golang.org/doc/articles/race_detector.html has more information about data races and the Go race detector - a very useful tool to identify hard-to-trace bugs in concurrent access.

相关阅读:
Top