注意:我发现了“嵌入”这个词。在标题是不好的选择,但我会保留它。
我看到很多代码都是这样的:
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()
我什么时候应该使用前者?或者稍后?
答案 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。)