注意:我发现标题中的“嵌入”一词是错误的选择,但我会保留。
我看到很多代码是这样的:
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()
我应该什么时候使用前一个或更晚的版本?
保持互斥锁接近要保护的数据是一种好习惯。如果互斥锁应该保护对结构值字段的并发访问,则将互斥锁添加为该结构的字段非常方便,因此其目的显而易见。
如果您的应用程序中只有一个“实例” A,那么也可以将互斥锁也设为全局变量。
A
如果您的应用程序要创建的多个值A,则需要保护所有这些值以防止并发访问(但只能单独访问,可以同时访问多个值),那么显然,全局互斥锁是一个不好的选择,它将限制并发访问。A在任何时间点的单个值。
将互斥量作为字段添加到结构中,您 自然 会为每个不同的结构值拥有一个单独的互斥体,负责保护包含该结构值(或其字段)的单个互斥量。
尽管在您的示例中未添加互斥锁,但它是一个常规的命名字段。在嵌入式领域声明省略字段名。
它的知名度和使用程度较小,但也很方便,您可以“真正地”将互斥体嵌入结构中,并且可以进行调用Lock(),Unlock()就好像它们将成为结构本身的一部分一样。看起来像这样:
Lock()
Unlock()
var hits struct { sync.Mutex n int } hits.Lock() hits.n++ hits.Unlock()
(此示例摘自您(可能)对Go不了解的10件事,幻灯片#3。)