在go中访问struct的不同成员是否安全?

时间:2015-04-07 16:35:57

标签: go mutex sync

从不同的goroutine访问不同的struct成员是否安全?

我明白在没有同步的情况下写入同一个变量是很糟糕的:

package main

type Apple struct {
    color string
    size  uint
}

func main() {
    apple := &Apple{}
    go func() {
        apple.color = "red"
    }()
    go func() {
        apple.color = "green"
    }()
}

但是你可以在没有任何同步的情况下写入不同的struct成员吗?

package main

type Apple struct {
    color string
    size  uint
}

func main() {
    apple := &Apple{}
    go func() {
        apple.color = "red"
    }()
    go func() {
        apple.size = 42
    }()
}

或者我应该使用chansync.Mutex吗?

1 个答案:

答案 0 :(得分:13)

从不同的线程访问不同的变量应该是安全的,而struct成员是不同的变量。所以是的它应该是安全的。

然而,它可能不会很快。与结构成员一样在内存中靠近的变量将共享CPU缓存行。缓存行是CPU(最好的,大多数当前型号)可以锁定的最小内存。这意味着CPU-2必须等待写入,直到CPU-1完成该缓存行,即使它们写入不同的变量。

从不同的线程写入结构时,更改指向结构的指针是不安全的。在你的例子中,如果你有第三个goroutine,apple = &Apple{}其他线程中的其他一些goroutine可能写入旧Apple或新Apple,你就不会知道。