假设我有一个程序,其中包含对映射表的并发访问,就像这样:
func getKey(r *http.Request) string { ... }
values := make(map[string]int)
http.HandleFunc("/get", func(w http.ResponseWriter, r *http.Request) {
key := getKey(r)
fmt.Fprint(w, values[key])
})
http.HandleFunc("/set", func(w http.ResponseWriter, r *http.Request) {
key := getKey(r)
values[key] = rand.Int()
})
这很糟糕,因为map的写操作是非原子的。所以我可以使用读写互斥锁。
func getKey(r *http.Request) string { ... }
values := make(map[string]int)
var lock sync.RWMutex
http.HandleFunc("/get", func(w http.ResponseWriter, r *http.Request) {
key := getKey(r)
lock.RLock()
fmt.Fprint(w, values[key])
lock.RUnlock()
})
http.HandleFunc("/set", func(w http.ResponseWriter, r *http.Request) {
key := getKey(r)
lock.Lock()
values[key] = rand.Int()
lock.Unlock()
})
这似乎很好,但问题在于我们直接使用互斥锁而不是通道。
有没有更符合Go语言的实现方式?或者这是那种只需要互斥锁就足够的时候?