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