Go博客中的" Go maps in action "条目指出:
映射对于并发使用是不安全的:它没有定义当您同时读取和写入时会发生什么.如果您需要从同时执行的goroutine中读取和写入映射,则访问必须由某种同步机制调解.保护地图的一种常用方法是使用sync.RWMutex.
但是,访问映射的一种常用方法是使用range关键字迭代它们.目前尚不清楚,为了并发访问的目的,range循环内的执行是"读",还是只是该循环的"周转"阶段.例如,以下代码可能会或可能不会与"无并发r/w映射"规则相冲突,具体取决于操作的特定语义/实现range:
var testMap map[int]int
testMapLock := make(chan bool, 1)
testMapLock <- true
testMapSequence := 0
Run Code Online (Sandbox Code Playgroud)
...
func WriteTestMap(k, v int) {
<-testMapLock
testMap[k] = v
testMapSequence++
testMapLock<-true
}
func IterateMapKeys(iteratorChannel chan int) error {
<-testMapLock
defer func() {
testMapLock <- true
}
mySeq := testMapSequence
for k, _ := range testMap {
testMapLock <- true
iteratorChannel <- k
<-testMapLock
if mySeq != testMapSequence {
close(iteratorChannel)
return errors.New("concurrent …Run Code Online (Sandbox Code Playgroud) 在从地图中删除项目之前,我是否先放锁?
package main
import (
"errors"
"sync"
"time"
)
type A struct {
Error error
}
func (a *A) Job() {
// ... more job
}
var l sync.RWMutex
func generate() {
l.Lock()
values["key1"] = A{}
l.Unlock()
l.Lock()
values["key2"] = A{}
values["key3"] = A{}
l.Unlock()
// ...
l.Lock()
values["key1919"] = A{Error: errors.New("oh...")}
l.Unlock()
// ...
l.Lock()
values["key99999999999"] = A{}
l.Unlock()
}
var values map[string]A
func main() {
values = make(map[string]A)
go generate()
for {
l.RLock()
for key, value := range …Run Code Online (Sandbox Code Playgroud)