在Go语言中,访问结构体的不同成员是否是线程安全的?

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

Is it thread safe to access different members of struct in go?

问题

从不同的goroutine访问不同的结构成员是安全的。在你的第一个示例中,同时写入同一个变量确实是危险的,因为没有同步机制。但是,在第二个示例中,你同时写入不同的结构成员,这是安全的,因为每个goroutine都在访问不同的内存位置。

你可以在不同的goroutine中同时写入不同的结构成员,而无需任何同步机制。这是因为每个结构成员都有自己的内存位置,不会相互干扰。

然而,如果你要在多个goroutine中同时写入相同的结构成员,就需要使用同步机制,如chansync.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.

huangapple
  • 本文由 发表于 2015年4月8日 00:35:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/29496605.html
匿名

发表评论

匿名网友

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

确定