Golangの`sync.WaitGroup`を理解する
Lukas Schneider
DevOps Engineer · Leapcell

Key Takeaways
sync.WaitGroupは、複数のゴルーチンを効率的に同期するのに役立ちます。Add、Done、およびWaitは、ゴルーチンの実行と完了を制御します。- 適切な使用法は、競合状態を防ぎ、プログラムの安定性を確保します。
Goでの並行プログラミングでは、複数のゴルーチンの同期を管理することが非常に重要です。Goの標準ライブラリのsync.WaitGroupは、他のゴルーチンで実行されている一連の操作が完了するのを待つための、シンプルで効果的な方法を提供します。この記事では、sync.WaitGroupの機能、使用法、および内部の仕組みについて詳しく説明します。
sync.WaitGroupとは?
sync.WaitGroupは、ゴルーチンが他のゴルーチンで実行されている一連の操作が完了するのを待つことを可能にする同期プリミティブです。指定されたすべてのゴルーチンが終了するまで、プログラムの実行をブロックする方法を提供します。
sync.WaitGroupの主要なメソッド
WaitGroupは、3つの主要なメソッドを提供します。
-
Add(delta int): 待機するゴルーチンの数を、指定されたdeltaだけ調整します。正の値は、新しいゴルーチンが追加されていることを示し、負の値は、ゴルーチンが完了したことを示します。 -
Done(): カウンターを1つ減らし、ゴルーチンがタスクを完了したことを示します。これは本質的にAdd(-1)の省略形です。 -
Wait(): カウンターがゼロになるまで、つまりすべてのゴルーチンがタスクを完了するまで、呼び出し元のゴルーチンの実行をブロックします。
sync.WaitGroupの使用
WaitGroupの使用方法を示す基本的な例を次に示します。
package main import ( "fmt" "sync" ) func worker(id int, wg *sync.WaitGroup) { defer wg.Done() fmt.Printf("Worker %d starting\n", id) // Simulate work fmt.Printf("Worker %d done\n", id) } func main() { var wg sync.WaitGroup for i := 1; i <= 5; i++ { wg.Add(1) go worker(i, &wg) } wg.Wait() }
この例では:
WaitGroup変数wgが宣言されています。Addメソッドは、ゴルーチンごとにカウンターを1つ増やします。- 各
worker関数は、完了時にDoneを呼び出し、カウンターを減らします。 Waitメソッドは、すべてのゴルーチンが終了するまで、main関数をブロックします。
WaitGroupの内部メカニズム
内部的には、WaitGroupはアクティブなゴルーチンの数を追跡するためにカウンターを保持します。Addメソッドはこのカウンターを変更し、Doneはそれを減らします。Waitメソッドは、カウンターがゼロになるまでブロックします。このメカニズムにより、メインゴルーチンは、すべての生成されたゴルーチンが完了してから続行することが保証されます。
重要な考慮事項
-
AddとWaitの呼び出しの一貫性:AddとWaitの呼び出しが同時に実行されないようにします。競合状態を避けるために、ゴルーチンを開始する前にAddを呼び出すことをお勧めします。 -
負のカウンターの回避: カウンターは負になるべきではありません。バランスを維持するために、各
Add呼び出しには対応するDone呼び出しが必要です。 -
再利用性:
Waitメソッドが返された後、以前のすべてのゴルーチンが完了し、新しいAdd呼び出しが行われていないことを確認しない限り、WaitGroupを再利用してはなりません。
結論
sync.WaitGroupは、Goの並行モデルの強力なツールであり、複数のゴルーチンを同期するための簡単な方法を提供します。そのメソッドと適切な使用法を理解することで、開発者は並行操作を効果的に管理し、プログラムが続行する前にすべてのゴルーチンがタスクを完了することを保証できます。
FAQs
これは、カウンターが負になることができないため、パニックを引き起こします。
はい、ただし、以前のすべてのゴルーチンが完了してから新しいゴルーチンを追加する場合に限ります。
競合状態を防ぎ、すべてのゴルーチンが正しくカウントされるようにするためです。
Leapcellは、Goプロジェクトをホストするための最良の選択肢です。
Leapcellは、Webホスティング、非同期タスク、およびRedisのための次世代サーバーレスプラットフォームです。
複数言語のサポート
- Node.js、Python、Go、またはRustで開発します。
無制限のプロジェクトを無料でデプロイ
- 使用量に応じてのみ支払い - リクエストも料金もありません。
比類のないコスト効率
- アイドル料金なしの従量課金制。
- 例:$25で、平均応答時間60msで694万リクエストをサポートします。
合理化された開発者エクスペリエンス
- 簡単なセットアップのための直感的なUI。
- 完全に自動化されたCI/CDパイプラインとGitOps統合。
- 実行可能なインサイトのためのリアルタイムメトリックとロギング。
簡単なスケーラビリティと高性能
- 高い同時実行性を簡単に処理するための自動スケーリング。
- 運用オーバーヘッドゼロ - 構築に集中するだけです。
ドキュメントで詳細をご覧ください!
Xでフォローしてください:@LeapcellHQ



