sync.WaitGroup
複数のゴルーチンの完了を待機します。
「sync.WaitGroup」はCoddyKit上の無料Go Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはGo Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Go Academyコースには全4レッスンが含まれています。
目的
sync.WaitGroupは、複数のゴルーチンが終了するまで待機します。メインゴルーチンがAddを呼び出してカウントを設定し、各ゴルーチンが処理の完了時にDoneを呼び出します。Waitはカウントがゼロになるまでブロックします。
基本的な使い方
各ゴルーチンを起動する前にAddを呼び出し、各ゴルーチンの最後でDoneを呼び出します(deferを使用します)。すべてのゴルーチンを起動した後にWaitを呼び出します。
var wg sync.WaitGroup
for _, item := range items {
wg.Add(1)
go func(v Item) {
defer wg.Done()
process(v)
}(item)
}
wg.Wait()Addはゴルーチンの開始前に実行する必要があります
wg.Add(1)はgo func()の前に呼び出し、ゴルーチンの内部では決して呼び出さないでください。そうしないと、ゴルーチンが自身を登録する前にWaitが戻る可能性があります。
よくある間違い: ループ変数のキャプチャ
すべてのゴルーチンが同じ変数を共有するのを避けるため、ループ変数はクロージャ経由ではなく、ゴルーチン関数の引数として渡します。
for _, v := range items {
wg.Add(1)
go func(item Item) { // correct: copy
defer wg.Done()
process(item)
}(v)
}WaitGroupの再利用
Waitが戻った後であればWaitGroupを再利用できます。ただし、以前のすべてのDone呼び出しが戻っている場合に限ります。Done呼び出しが未完了の状態で同時に再利用しないでください。
結果を扱うWaitGroup
WaitGroupは結果を収集しません。ゴルーチンの出力を集めるには、チャネルまたは(mutexと組み合わせた)スライスと併用します。
results := make([]Result, len(items))
for i, item := range items {
wg.Add(1)
go func(idx int, v Item) {
defer wg.Done()
results[idx] = process(v)
}(i, item)
}
wg.Wait()バッチ数を指定したAdd
ループの前に1回のAdd呼び出しへ合計数を渡すこともできます。ゴルーチンごとにAddを1回ずつ呼び出すより、わずかに効率的です。
wg.Add(len(items))
for _, item := range items {
go func(v Item) { defer wg.Done(); process(v) }(item)
}WaitGroupをコピーしないでください
Mutexと同様に、WaitGroupは一度使用した後にコピーしてはいけません。ポインターで渡すか、ポインターで渡す構造体に埋め込みます。
WaitGroupとerrgroupの比較
golang.org/x/sync/errgroupはWaitGroupをラップし、エラーの伝播機能を追加します。いずれかのゴルーチンの失敗時に他のゴルーチンも停止する必要がある場合は、errgroupを優先します。
contextとの組み合わせ
WaitGroupのセマンティクスと、最初のエラーでキャンセルされるcontextの両方を得るには、errgroup.WithContextを使用します。これにより、すべてのゴルーチンを適切に停止できます。
g, ctx := errgroup.WithContext(context.Background())
g.Go(func() error { return doWork(ctx) })
if err := g.Wait(); err != nil { log.Fatal(err) }ゼロ値をそのまま使用できます
sync.WaitGroupのゼロ値はすぐに使用できます。コンストラクターは必要ありません。宣言してAddを呼び出すだけです。
確認問題
ゴルーチンを起動する前ではなく、ゴルーチンの内部でwg.Add(1)を呼び出すとどうなりますか。
まとめ: sync.WaitGroup
要点:
- ゴルーチンを起動する前にAddを呼び出し、ゴルーチン内ではdeferを使ってDoneを呼び出します
- Waitはカウントがゼロになるまでブロックします
- コピーしてはいけません。ゴルーチン内でAddを呼び出してはいけません
- エラーを伝播するにはerrgroupを使用します
よくある質問
「sync.WaitGroup」レッスンは無料ですか?
はい。「sync.WaitGroup」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Go Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Go Academyコースには全4レッスンが含まれています。
「sync.WaitGroup」で何を学びますか?
複数のゴルーチンの完了を待機します。 ブラウザで直接実行するハンズオンコードでGo Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Go Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのGo Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「sync.WaitGroup」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このGo Academyレッスンでコードを書いて実行できますか?
はい。すべてのGo Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- sync.Mutexとsync.RWMutex
- sync.WaitGroup
- sync.Onceとsync.Map
- 競合検出器と安全なパターン