type MyMap struct {
data map[int]int
}
func (m Mymap)foo(){
//insert or read from m.data
}
...
go func f (m *Mymap){
for {
//insert into m.data
}
}()
...
Var m Mymap
m.foo()
当我调用m.foo()时,正如我们所知,有一个" m",值复制的副本,由编译器完成。我的问题是,程序中是否存在竞争?它是来自var" m"的某种读取数据,我的意思是,如果有人在从m.data复制内容时将值插入m.data,则可能需要读锁定。
如果它是线程安全的,它是否由编译器保护?
答案 0 :(得分:2)
这不安全,并且语言中没有隐含的安全并发访问权限。所有并发数据访问都是不安全的,需要使用通道或锁保护。
因为地图内部包含对它们包含的数据的引用,即使复制了外部结构,地图仍然指向相同的数据。并发映射通常是常见的要求,您需要做的就是添加一个互斥锁来保护读写操作。虽然Mutex指针可以与您的值接收器一起使用,但使用指针接收器来改变方法更为惯用。
type MyMap struct {
sync.Mutex
data map[int]int
}
func (m *MyMap) foo() {
m.Lock()
defer m.Unlock()
//insert or read from m.data
}
go memory model非常明确,比赛通常很容易推理。如有疑问,请始终使用-race
运行您的程序或测试。