你啥时候在 Go 的 struct 中嵌入互斥锁?
Posted
技术标签:
【中文标题】你啥时候在 Go 的 struct 中嵌入互斥锁?【英文标题】:When do you embed mutex in struct in Go?你什么时候在 Go 的 struct 中嵌入互斥锁? 【发布时间】:2017-12-10 11:51:30 【问题描述】:注意:我发现标题中的“嵌入”一词是错误的选择,但我会保留它。
我看到很多代码都是这样的:
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 上的方法表达式。如果您要询问每个结构实例使用单个互斥锁或单个全局互斥锁;您需要全局互斥锁还是要单独锁定每个实例?这取决于您要完成的工作。 谢谢。我改变了我的代码。 【参考方案1】:最好让互斥锁靠近它要保护的数据。如果互斥锁应该保护对结构值字段的并发访问,则将互斥锁添加为该结构的字段非常方便,因此其目的很明显。
如果在您的应用中只有一个“实例”A
,也可以将互斥锁设为全局变量。
如果你的应用要创建A
的多个值,所有这些都需要被保护以防止并发访问(但只能单独地,多个值可能被同时访问),那么显然全局互斥锁是一个不好的选择,它将在任何时间点将并发访问限制为A
的单个值。
将互斥锁作为字段添加到结构中,自然为每个不同的结构值都有一个单独的互斥锁,负责保护单个包装器结构值(或其字段)。 p>
虽然在您的示例中添加互斥锁不是嵌入,但它是一个常规的命名字段。 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。)
【讨论】:
以上是关于你啥时候在 Go 的 struct 中嵌入互斥锁?的主要内容,如果未能解决你的问题,请参考以下文章