你什么时候在Go中嵌入mutex?

时间:2017-07-06 12:53:28

标签: go struct embed mutex

注意:我发现了“嵌入”这个词。在标题是不好的选择,但我会保留它。

我看到很多代码都是这样的:

type A struct {
    mu sync.Mutex
    ...
}

并像这样使用它:

a := &A{}

a.mu.Lock()
defer a.mu.Unlock()

a.Something()

它是否优于本地互斥或全局互斥?

a := &A{}

var mu sync.Mutex
mu.Lock()
defer mu.Unlock()

a.Something()

我什么时候应该使用前者?或者稍后?

1 个答案:

答案 0 :(得分:18)

最好将互斥锁保持接近其预定要保护的数据。如果互斥锁应该保护对结构值字段的并发访问,那么将互斥锁添加为该结构的字段非常方便,因此其目的很明显。

如果在您的应用中只有A的单个“实例”,那么将互斥锁也设为全局变量也是可以的。

如果您的应用要创建多个A值,则需要保护所有这些值不受并发访问的限制(但只能单独访问,并且可以同时访问多个值),那么显然全局互斥是一个糟糕的选择,它会限制在任何时间点对A的单个值的并发访问。

将互斥体作为字段添加到结构中,自然为每个不同的结构值都有一个单独的互斥锁,负责保护包含结构值(或其字段)的单个结构值。

尽管在示例中添加互斥锁不是嵌入,但它是一个常规的命名字段。 embedded field declaration省略了字段名称。

它已知并在较小程度上使用,但您可以“真正”在结构中嵌入互斥锁也很方便,您可以调用Lock()Unlock(),就好像它们会成为一部分一样结构本身。它看起来像这样:

var hits struct {
    sync.Mutex
    n int
}

hits.Lock()
hits.n++
hits.Unlock()

(此示例取自10 things you (probably) don't know about Go, slide #3。)