タスクの分配と負荷の分散におけるGo WaitGroupの活用

Go言語では、WaitGroupは一連のgoroutineの実行を待機するための機能を提供します。複数の並列タスクの実行と待機を調整し、すべてのタスクが完了したことを確認してからメインスレッドの実行を続行します。

WaitGroupの使い方に関する簡単な例を次に示します。

package main
import (
"fmt"
"sync"
"time"
)
func worker(id int, wg *sync.WaitGroup) {
defer wg.Done()
fmt.Printf("Worker %d starting\n", id)
time.Sleep(time.Second)
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()
fmt.Println("All workers done")
}

この例では `worker` 関数を定義していて、`id` と `WaitGroup` 引数を受け取ります。関数が開始すると、`wg.Done()` を呼び出して、タスクの完了を `WaitGroup` に通知します。メイン関数では、5 つの `worker` ゴルーチンを作成するループを実行し、各ゴルーチンを開始する前に `wg.Add(1)` を呼び出して `WaitGroup` のカウントを増やします。最後に、`wg.Wait()` を呼び出して、すべてのゴルーチンの実行が完了するのを待ちます。

出力結果は次のようになります。

Worker 1 starting
Worker 5 starting
Worker 2 starting
Worker 3 starting
Worker 4 starting
Worker 4 done
Worker 1 done
Worker 2 done
Worker 3 done
Worker 5 done
All workers done

WaitGroupのカウンタが負の数値にならないように注意する必要があります。そのため、各ゴリルーチンでwg.Add(1)が実行されるまでwg.Done()を呼び出す必要があります。

WaitGroup には wg.Add(delta int) というよく使われるメソッドがあり、カウンタの値を一括して増減させることができます。これは、タスクの分散と負荷の分散にも非常に役立ちます。

例えば、タスクのリストがあり、タスクを goroutine のグループに割り当てて並列処理したい場合は、WaitGroupを使用してすべてのタスクが完了するのを待機できます。タスクを割り当てるときは、wg.Add(len(tasks))を使用してWaitGroupのカウンタを一括で増やし、各goroutineがタスクを完了するとwg.Done()を呼び出してカウンタを減らします。

Go言語のWaitGroupは、並列に実行した複数のタスクの実行待ちを調整する非常に便利な機能です。WaitGroupを適切に使用することで、タスクの振り分けと負荷分散を実現し、並列処理の性能と効率を向上させることができます。

bannerAds