在go中访问struct的不同成员是否线程安全?
Is it thread safe to access different members of struct in go?
从不同的 goroutines 访问不同的结构成员是否安全?
我知道在没有同步的情况下写入同一个变量是危险的:
package main
type Apple struct {
color string
size uint
}
func main() {
apple := &Apple{}
go func() {
apple.color = "red"
}()
go func() {
apple.color = "green"
}()
}
但是你可以在没有任何同步的情况下写入不同的结构成员吗?
package main
type Apple struct {
color string
size uint
}
func main() {
apple := &Apple{}
go func() {
apple.color = "red"
}()
go func() {
apple.size = 42
}()
}
或者我应该使用 chan
还是 sync.Mutex
?
不同线程访问不同变量应该是安全的,struct成员是不同的变量。所以是的,它应该是安全的。
但是,它可能不会很快。在内存中靠近在一起的变量(如结构成员)将共享一个 CPU 缓存行。缓存行是 CPU(好吧,大多数当前模型)可以锁定的最小内存块。这意味着 CPU-2 必须等到 CPU-1 完成该缓存行后才写入,即使它们正在写入不同的变量。
在从不同线程写入结构时更改指向结构的指针是不安全的。在您的示例中,如果您有第三个 goroutine apple = &Apple{}
其他线程中的一些其他 goroutine 可能会写入旧 Apple 或新 Apple 而您不会知道。
从不同的 goroutines 访问不同的结构成员是否安全?
我知道在没有同步的情况下写入同一个变量是危险的:
package main
type Apple struct {
color string
size uint
}
func main() {
apple := &Apple{}
go func() {
apple.color = "red"
}()
go func() {
apple.color = "green"
}()
}
但是你可以在没有任何同步的情况下写入不同的结构成员吗?
package main
type Apple struct {
color string
size uint
}
func main() {
apple := &Apple{}
go func() {
apple.color = "red"
}()
go func() {
apple.size = 42
}()
}
或者我应该使用 chan
还是 sync.Mutex
?
不同线程访问不同变量应该是安全的,struct成员是不同的变量。所以是的,它应该是安全的。
但是,它可能不会很快。在内存中靠近在一起的变量(如结构成员)将共享一个 CPU 缓存行。缓存行是 CPU(好吧,大多数当前模型)可以锁定的最小内存块。这意味着 CPU-2 必须等到 CPU-1 完成该缓存行后才写入,即使它们正在写入不同的变量。
在从不同线程写入结构时更改指向结构的指针是不安全的。在您的示例中,如果您有第三个 goroutine apple = &Apple{}
其他线程中的一些其他 goroutine 可能会写入旧 Apple 或新 Apple 而您不会知道。