什么时候在Go的结构中嵌入互斥?

什么时候在Go的结构中嵌入互斥?,go,struct,embed,mutex,Go,Struct,Embed,Mutex,注意:我发现标题中的“嵌入”一词是个糟糕的选择,但我会保留它 我看到很多代码都是这样的: type A struct { mu sync.Mutex ... } a := &A{} a.mu.Lock() defer a.mu.Unlock() a.Something() var hits struct { sync.Mutex n int } hits.Lock() hits.n++ hits.Unlock() 然后像这样使用它: type

注意:我发现标题中的“嵌入”一词是个糟糕的选择,但我会保留它

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

type A struct {
    mu sync.Mutex
    ...
}
a := &A{}

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

a.Something()
var hits struct {
    sync.Mutex
    n int
}

hits.Lock()
hits.n++
hits.Unlock()
然后像这样使用它:

type A struct {
    mu sync.Mutex
    ...
}
a := &A{}

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

a.Something()
var hits struct {
    sync.Mutex
    n int
}

hits.Lock()
hits.n++
hits.Unlock()
它比本地互斥或全局互斥更好吗

a := &A{}

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

a.Something()

什么时候应该使用前者,还是更高版本?

最好将互斥锁保持在它要保护的数据附近。如果互斥体应该保护对结构值字段的并发访问,那么将互斥体添加为该结构的字段是非常方便的,因此其目的是显而易见的

如果您的应用程序中只有一个
a
的“实例”,那么也可以将互斥体设置为全局变量

如果您的应用程序要创建多个
A
,所有这些值都需要防止并发访问(但只能单独地,多个值可以并发访问),那么显然,全局互斥锁是一个错误的选择,它会在任何时间点将并发访问限制为单个
A

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

虽然在示例中添加互斥不是嵌入,但它是一个常规的命名字段。省略字段名

它的知名度和使用程度较低,但也很方便,您可以“真正”在结构中嵌入互斥体,并且可以调用
Lock()
Unlock()
,就好像它们是结构本身的一部分一样。看起来是这样的:

type A struct {
    mu sync.Mutex
    ...
}
a := &A{}

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

a.Something()
var hits struct {
    sync.Mutex
    n int
}

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

(此示例取自。)

您的第一个示例不起作用,因为如果没有显式接收器,您无法在上调用方法表达式。如果您询问每个结构实例使用一个互斥体,或者使用一个全局互斥体;您需要全局互斥还是要单独锁定每个实例?这取决于你想完成什么。谢谢。我改了密码。