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

fra*_*lin 5 thread-safety go

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()
Run Code Online (Sandbox Code Playgroud)

当我调用m.foo()时,正如我们所知,有一个"m",值复制的副本,由编译器完成.我的问题是,程序中是否有竞争?它是来自var"m"的某种读取数据,我的意思是,如果有人在从m.data复制内容时将值插入m.data,则可能需要读取锁定.

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

Jim*_*imB 2

这是不安全的,并且该语言中没有隐含的安全并发访问。所有并发数据访问都是不安全的,需要使用通道或锁进行保护。

因为映射内部包含对其所包含数据的引用,所以即使复制了外部结构,映射仍然指向相同的数据。并发映射通常是一个常见的需求,您所需要做的就是添加一个互斥体来保护读取和写入。尽管互斥指针可以与您的值接收器一起使用,但使用指针接收器来改变方法更为惯用。

type MyMap struct {
    sync.Mutex
    data map[int]int
}

func (m *MyMap) foo() {
    m.Lock()
    defer m.Unlock()
    //insert  or read from m.data
}
Run Code Online (Sandbox Code Playgroud)

围棋内存模型非常明确,并且竞争通常很容易推理。如有疑问,请始终使用-race.