注:タイトルに「埋め込み」という単語を使用するのは不適切な選択でしたが、そのままにしておきます。
私は多くのコードがこのようになっているのを見ます:
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
の単一の値に制限します。
ミューテックスをフィールドとして構造体に追加すると、当然個別の構造体値ごとに個別のミューテックスが作成され、構造体値を含むその単一の構造体を保護する責任があります。 (またはそのフィールド)。
あなたの例のようにミューテックスを追加することは埋め込みではありませんが、それは通常の名前付きフィールドです。 埋め込みフィールド宣言 はフィールド名を省略します。
あまり知られておらず、あまり使用されていませんが、構造体にミューテックスを「本当に」埋め込むことができ、Lock()
とUnlock()
をまるで呼び出すことができるのも便利です。構造体自体の一部。次のようになります。
var hits struct {
sync.Mutex
n int
}
hits.Lock()
hits.n++
hits.Unlock()
(この例は Goについて(おそらく)知らない10のこと、スライド# から抜粋したものです。)