何时在Go中嵌入互斥结构? [英] When do you embed mutex in struct in Go?
问题描述
我看到很多代码都是这样的:
type结构{
mu sync.Mutex
...
}
然后像这样使用它:
a:=& A {}
a。 mu.Lock()
推迟a.mu.Unlock()
a.Something()
是否比本地互斥或全局互斥更好?
a:=& A { }
var mu sync.Mutex
mu.Lock()
defer mu.Unlock()
a.Something()
何时应使用前者或后期?
最好让互斥量接近它要保护的数据。如果互斥量应该保护并发访问结构值的字段,那么将互斥量作为该结构的字段添加是非常方便的,因此它的目的显而易见。
如果在您的应用程序中只有一个 A
的实例,那么也可以将互斥锁作为全局变量。
如果您的应用程序要创建 A
的多个值,则需要保护所有这些值不受并发访问的限制(但只能单独使用,可同时访问多个值) ,那么显然全局互斥是一个不好的选择,它会限制在任何时间点同时访问单个值 A
。
将结构体中的互斥体作为一个字段添加,你会自然地为每个不同的结构体赋值一个单独的互斥体,负责保护单个结构体的值(或其字段)。
虽然在您的示例中添加互斥量不是嵌入,但它是一个常规的命名字段。 嵌入式字段声明省略了字段名称。
它是已知的并在较小程度上使用,但也可以真正将互斥体嵌入到结构中,并且可以调用 Lock()
和 Unlock()
就好像它们是结构本身的一部分一样。它看起来像这样:
var hits struct {
sync.Mutex
n int
}
hits.Lock()
hits.n ++
hits.Unlock()
(本例取自 10件事(可能)不知道Go,slide#3 。)
NOTE: I found the word 'embed' in the title was bad choice, but I will keep it.
I see a lot of code does like this:
type A struct {
mu sync.Mutex
...
}
And use it like this:
a := &A{}
a.mu.Lock()
defer a.mu.Unlock()
a.Something()
Is it better than local mutex or global mutex?
a := &A{}
var mu sync.Mutex
mu.Lock()
defer mu.Unlock()
a.Something()
When should I use former, or later?
It's good practice to keep the mutex close to the data it is destined to protect. If a mutex ought to protect concurrent access to fields of a struct value, it's very convenient to add the mutex as a field of that struct, so its purpose is obvious.
If in your app there is only a single "instance" of A
, it's fine to make the mutex a global variable too.
If your app is to create multiple values of A
, all of which needs to be protected from concurrent access (but only individually, multiple values may be accessed concurrently), then obviously a global mutex is a bad choice, it would limit the concurrent access to a single value of A
in any point in time.
Adding the mutex to the struct as a field, you will naturally have a separate mutex for each distinct struct values, responsible to guard that single, containing struct value (or its fields).
Although adding a mutex as in your example is not embedding, it's a regular, named field. An embedded field declaration omits the field name.
It's known and used to a lesser extent, but it's also handy that you can "truly" embed a mutex in a struct, and you can call Lock()
and Unlock()
as if they would be part of the struct itself. It looks like this:
var hits struct {
sync.Mutex
n int
}
hits.Lock()
hits.n++
hits.Unlock()
(This example is taken from 10 things you (probably) don't know about Go, slide #3.)
这篇关于何时在Go中嵌入互斥结构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!