Thread Safe In Value Receiver In Go

huangapple go评论68阅读模式
英文:

Thread Safe In Value Receiver In Go

问题

type MyMap struct {
data map[int]int
}

func (m Mymap)foo(){

//从m.data中插入或读取数据

}

...

go func f (m *Mymap){
for {
//向m.data中插入数据
}
}()

...

var m Mymap

m.foo()

当我调用m.foo()时,我们知道,编译器会对"m"进行值拷贝。我的问题是,在这个过程中是否存在竞争条件?也就是说,当你从m.data中复制数据时,如果有人正在向m.data中插入值,你可能需要一个读锁。

如果它是线程安全的,这是由编译器保证的吗?

英文:
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()

When I call m.foo(), as we know , there is a copy of "m",value copy ,which is done by compiler 。 My question is , is there a race in the procedure? It is some kind of reading data from the var "m", I mean , you may need a read lock in case someone is inserting values into m.data when you are copying something from m.data.

If it is thread-safe , is it guarenteed by compiler?

答案1

得分: 2

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

因为映射内部包含对其所包含数据的引用,即使外部结构被复制,映射仍然指向相同的数据。并发映射通常是一个常见的需求,你只需要添加一个互斥锁来保护读写操作。虽然在值接收器中使用互斥锁指针也可以工作,但使用指针接收器来进行变异方法更符合惯例。

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

func (m *MyMap) foo() {
    m.Lock()
    defer m.Unlock()
    //插入或从m.data读取
}

Go的内存模型非常明确,竞争通常很容易推理。如果有疑问,始终使用-race选项运行程序或测试。

英文:

This is not safe, and there is no implied safe concurrent access in the language. All concurrent data access is unsafe, and needs to be protected with channels or locks.

Because maps internally contain references to the data they contain, even as the outer structure is copied the map still points to the same data. A concurrent map is often a common requirement, and all you need to do is add a mutex to protect the reads and writes. Though a Mutex pointer would work with your value receiver, it's more idiomatic to use a pointer receiver for mutating methods.

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

func (m *MyMap) foo() {
	m.Lock()
	defer m.Unlock()
	//insert  or read from m.data
}

The go memory model is very explicit, and races are generally very easy to reason about. When in doubt, always run your program or tests with -race.

huangapple
  • 本文由 发表于 2014年7月29日 11:02:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/25007624.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定