2 回答
TA贡献1786条经验 获得超13个赞
Golang 1.6之前并发读可以,并发写不行,写并发读可以。从 Golang 1.6 开始,map 在写入时无法读取。所以在 Golang 1.6 之后,并发访问映射应该是这样的:
package main
import (
"sync"
"time"
)
var m = map[string]int{"a": 1}
var lock = sync.RWMutex{}
func main() {
go Read()
time.Sleep(1 * time.Second)
go Write()
time.Sleep(1 * time.Minute)
}
func Read() {
for {
read()
}
}
func Write() {
for {
write()
}
}
func read() {
lock.RLock()
defer lock.RUnlock()
_ = m["a"]
}
func write() {
lock.Lock()
defer lock.Unlock()
m["b"] = 2
}
或者你会得到以下错误:
添加:
您可以通过使用检测种族 go run -race race.go
更改read功能:
func read() {
// lock.RLock()
// defer lock.RUnlock()
_ = m["a"]
}
另一种选择:
众所周知,map
是由桶实现的,sync.RWMutex
会锁定所有的桶。concurrent-map用于fnv32
对键进行分片,每个存储桶使用一个sync.RWMutex
.
TA贡献1810条经验 获得超5个赞
运行时添加了轻量级、尽力而为的并发误用映射检测。与往常一样,如果一个 goroutine 正在写入地图,则没有其他 goroutine 应该同时读取或写入地图。如果运行时检测到这种情况,它会打印诊断信息并使程序崩溃。找出更多问题的最好方法是在比赛检测器下运行程序,这将更可靠地识别比赛并提供更多细节。
映射是复杂的、自重组的数据结构。并发读写访问未定义。
没有代码,没有什么可说的。
- 2 回答
- 0 关注
- 156 浏览
添加回答
举报