Go Wiki: sync.Mutex とチャネルのどちらを使うべきか
Go のモットーの1つは、「メモリを共有して通信するのではなく、通信によってメモリを共有する」です。
とはいえ、Go は sync パッケージで伝統的なロックメカニズムを提供しています。ほとんどのロックの問題は、チャネルまたは伝統的なロックのいずれかを使用して解決できます。
では、どちらを使用すべきでしょうか?
最も表現力があり、かつ/または最もシンプルな方を使用してください。
Go の初心者が陥りがちな間違いは、チャネルとゴルーチンを、単に可能だから、あるいは楽しいからといって過度に使用することです。問題に最も適している場合は、sync.Mutex を使用することを恐れないでください。Go は、問題を最もよく解決するツールを使用することを許容し、コードの特定のスタイルを強制しないという点で実用的です。
一般的なガイドラインとして
| チャネル | ミューテックス |
|---|---|
| データの所有権の引き渡し 作業単位の分散 非同期の結果の通信 | キャッシュ 状態 |
もし sync.Mutex のロックルールが複雑になりすぎていると感じたら、チャネルを使うともっとシンプルになるかもしれないと考えてみてください。
Wait Group
もう一つの重要な同期プリミティブは sync.WaitGroup です。これらを使用すると、協力するゴルーチンが集合的にある閾値イベントを待機し、その後再び独立して進行することができます。これは通常、2つのケースで役立ちます。
まず、'クリーンアップ' の際、sync.WaitGroup を使用して、メインゴルーチンを含むすべてのゴルーチンが、すべてきれいに終了するまで待機するようにできます。
2つ目のより一般的なケースは、一連のゴルーチンがしばらく独立して作業し、その後すべてバリアで待機し、再び独立して進行するという、循環的なアルゴリズムの場合です。このパターンは何度も繰り返されることがあります。バリアイベントでデータが交換されることがあります。この戦略は、バルク同期並列処理 (BSP) の基礎となります。
チャネル通信、ミューテックス、および待機グループは補完的であり、組み合わせて使用できます。
詳細情報
- Effective Go のチャネル: https://go.dokyumento.jp/doc/effective_go#channels
- sync パッケージ: https://pkg.go.dev/sync/
このコンテンツはGo Wikiの一部です。