英文:
Is it thread safe to access different members of struct in go?
问题
从不同的goroutine访问不同的结构成员是安全的。在你的第一个示例中,同时写入同一个变量确实是危险的,因为没有同步机制。但是,在第二个示例中,你同时写入不同的结构成员,这是安全的,因为每个goroutine都在访问不同的内存位置。
你可以在不同的goroutine中同时写入不同的结构成员,而无需任何同步机制。这是因为每个结构成员都有自己的内存位置,不会相互干扰。
然而,如果你要在多个goroutine中同时写入相同的结构成员,就需要使用同步机制,如chan
或sync.Mutex
,以确保并发访问的安全性。这样可以避免竞态条件和数据不一致的问题。
英文:
Is it safe to access different struct members from different goroutines?
I understand that writing to the same variable without sync is dangareous:
package main
type Apple struct {
color string
size uint
}
func main() {
apple := &Apple{}
go func() {
apple.color = "red"
}()
go func() {
apple.color = "green"
}()
}
But can you write to different struct members without any kind of synchronization?
package main
type Apple struct {
color string
size uint
}
func main() {
apple := &Apple{}
go func() {
apple.color = "red"
}()
go func() {
apple.size = 42
}()
}
Or should I use chan
or sync.Mutex
for that?
答案1
得分: 34
从不同的线程访问不同的变量应该是安全的,而结构体成员就是不同的变量。所以是的,应该是安全的。
然而,可能不会很快。在内存中靠近的变量(比如结构体成员)会共享一个CPU缓存行。缓存行是CPU(大多数当前型号)可以锁定的最小内存块。这意味着,即使它们在写入不同的变量,CPU-2必须等待CPU-1完成对该缓存行的操作才能进行写入。
在从不同的线程写入结构体时,更改结构体指针是不安全的。在你的示例中,如果有第三个goroutine执行了apple = &Apple{}
,其他线程中的一些goroutine可能会写入旧的Apple或新的Apple,而你无法得知。
英文:
It should be safe to access different variables from different threads, and struct members are different variables. So yes it should be safe.
However, it may not be fast. Variables that are close together in memory like struct members are will share a CPU cache line. A cache line is the smallest piece of memory that a CPU (well, most current models) can lock. That means that CPU-2 has to wait to write until CPU-1 has finished with that cache line even if they are writing to different variables.
It is NOT safe to change the pointer to the struct while writing to the struct from different threads. In your example if you had a third goroutine that did apple = &Apple{}
some of the other goroutines in other threads might write to the old Apple or the new Apple and you wouldn't know.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论