fatal error:concurrent map read and map write
Maps are not safe for concurrent use:it's not defined what happens when you read and write to them simultaneously. If you need to read from and write to a map from concurrently executing goroutines, the accesses must be mediated by some kind of synchronization mechanism. One common way to protect maps is with sync.RWMutex
map为引用类型,即使函数传值调用,行参副本依然指实参映射m, 所以多个goroutine并发写同一个映射m, 对于共享变量,资源,并发读写会产生竞争的, 故共享资源遭到破坏
可以通过加锁自定义一个SafeMap结构体,来避免以上错误.
package storage
import(
"sync"
)
typeSafeMapstruct{
lock*sync.RWMutex
smmap[interface{}]interface{}
}
funcNewSafeMap()*SafeMap{
return&SafeMap{
lock:new(sync.RWMutex),
sm:make(map[interface{}]interface{}),
}
}
func(m*SafeMap)Get(kinterface{})interface{}{
m.lock.RLock()
deferm.lock.RUnlock()
ifval,ok:=m.sm[k];ok{
returnval
}
returnnil
}
func(m*SafeMap)Set(k,vinterface{})bool{
m.lock.Lock()
deferm.lock.Unlock()
ifval,ok:=m.sm[k];!ok{
m.sm[k]=v
}elseifval!=nil{
m.sm[k]=v
}else{
returnfalse
}
returntrue
}
// Check Returns true if k is exist in the map.
func(m*SafeMap)Check(kinterface{})bool{
m.lock.RLock()
deferm.lock.RUnlock()
_,ok:=m.sm[k]
returnok
}
// Delete the given key and value.
func(m*SafeMap)Delete(kinterface{}){
m.lock.Lock()
deferm.lock.Unlock()
delete(m.sm,k)
}
// Items returns all items in safemap.
func(m*SafeMap)Items()map[interface{}]interface{}{
m.lock.RLock()
deferm.lock.RUnlock()
r:=make(map[interface{}]interface{})
fork,v:=rangem.sm{
r[k]=v
}
returnr
}
// Count returns the number of items within the map.
func(m*SafeMap)Count()int{
m.lock.RLock()
deferm.lock.RUnlock()
returnlen(m.sm)
}
网友评论