我是围棋语言的新手。执行代码时,出现以下错误:
致命错误:并发地图读取和地图写入
func foo() {
var m = map[string]int{"a": 1}
var lock = sync.RWMutex{}
go Read(m, lock)
time.Sleep(1 * time.Second)
go Write(m, lock)
time.Sleep(1 * time.Minute)
}
func main() {
foo()
}
func Read(m map[string]int, lock sync.RWMutex) {
for {
read(m, lock)
}
}
func Write(m map[string]int, lock sync.RWMutex) {
for {
write(m, lock)
}
}
func read(m map[string]int, lock sync.RWMutex) {
lock.RLock()
defer lock.RUnlock()
_ = m["a"]
}
func write(m map[string]int, lock sync.RWMutex) {
lock.Lock()
defer lock.Unlock()
m["b"] = 2
}
有人可以告诉我为什么吗?
答案 0 :(得分:8)
您必须传递一个指向您的sync.RWMutex
值的指针。否则,您每次将互斥锁传递给新功能时都将复制该互斥锁,因此不会发生实际的锁定。
go vet
工具将为您检测到此错误。您应该在所有代码上运行go vet
(可能还有other linters),以帮助捕获此类常见错误。 Related reading。