线程安全在价值接收器在Go

时间:2014-07-29 03:02:28

标签: go thread-safety

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,则可能需要读锁定。

如果它是线程安全的,它是否由编译器保护?

1 个答案:

答案 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运行您的程序或测试。