ワーカープールパターン
固定サイズのゴルーチンワーカープールを構築します。
「ワーカープールパターン」はCoddyKit上の無料Go Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはGo Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Go Academyコースには全4レッスンが含まれています。
ワーカープールとは何か
ワーカープールは、一定数のゴルーチンをあらかじめ作成し、共有キューからジョブを処理します。これにより並行実行数に上限を設け、ゴルーチンの無制限な作成によるリソース枯渇を防ぎます。
基本実装
jobs チャネルと、そこから読み取る N 個のゴルーチンを作成します:
func workerPool(n int, jobs <-chan Job, results chan<- Result) {
var wg sync.WaitGroup
for i := 0; i < n; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for job := range jobs {
results <- process(job)
}
}()
}
wg.Wait()
close(results)
}ジョブの送信
すべてのジョブをチャネルに送信してから、チャネルを閉じます。ワーカーはすべてのジョブを処理し、チャネルが閉じると range ループを終了します。
jobs := make(chan Job, 100)
for _, j := range allJobs {
jobs <- j
}
close(jobs) // signals workers to stop after draining結果の収集
ジョブの送信と同時に結果を読み取ります。ジョブの送信と結果の収集がデッドロックしないように、プールをゴルーチンで実行します。
results := make(chan Result, 100)
go workerPool(5, jobs, results)
for r := range results {
collect(r)
}プールサイズの調整
CPU バウンドの処理では、プールサイズを runtime.NumCPU() に設定します。I/O バウンドの処理では、より大きな倍率(例: 10×)にすると待機時間を活用できます。プロファイリングを行って最適な値を見つけます。
n := runtime.NumCPU()
if ioHeavy { n = runtime.NumCPU() * 10 }コンテキストによるキャンセルの追加
キャンセル時にワーカーが早期終了できるよう、ワーカーにコンテキストを渡します:
for {
select {
case job, ok := <-jobs:
if !ok { return }
results <- process(ctx, job)
case <-ctx.Done():
return
}
}セマフォという代替手段
固定のゴルーチンプールの代わりに、バッファ付きチャネルをセマフォとして使用できます。ジョブごとに1つのゴルーチンを起動しながら、同時に実行できるゴルーチン数を制限できます。
sem := make(chan struct{}, 10)
for _, job := range jobs {
sem <- struct{}{}
go func(j Job) {
defer func() { <-sem }()
process(j)
}(job)
}エラー処理
結果構造体を使用して、結果とともにエラーを返します。最初のエラーが発生した時点でコンテキストをキャンセルするか、すべてのエラーを収集して最後に報告します。
type Result struct{ Val int; Err error }動的なプールサイズ設定
適応型プールには golang.org/x/sync/semaphore を使用します。重み付きリソースの取得と解放が可能で、並行実行数の上限を動的に変更できます。
ワーカープールとerrgroupの比較
golang.org/x/sync/errgroup は、N 個のゴルーチンを起動し、最初のエラーを収集するための、よりシンプルな API を提供します。再利用可能なワーカーを一定数維持する必要がある場合は、プールを使用します。
正常なシャットダウン
ワーカーに通知するには jobs チャネルを閉じます。WaitGroup の処理が完了したら、results を閉じます。保留中のジョブ送信はすべて close(jobs) より前に行う必要があります。
確認問題
ワーカープールは、ワーカーに処理を停止することをどのように伝えますか?
復習: ワーカープール
重要なポイント:
- 固定数 N 個のゴルーチンが1つの jobs チャネルから読み取ります
- ワーカーに処理の終了を伝えるには jobs チャネルを閉じます
- WaitGroup が完了を追跡し、処理が終わったら results を閉じます
- CPU バウンド: プールサイズは NumCPU に近づけます。I/O バウンド: より大きくします
よくある質問
「ワーカープールパターン」レッスンは無料ですか?
はい。「ワーカープールパターン」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Go Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Go Academyコースには全4レッスンが含まれています。
「ワーカープールパターン」で何を学びますか?
固定サイズのゴルーチンワーカープールを構築します。 ブラウザで直接実行するハンズオンコードでGo Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Go Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのGo Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「ワーカープールパターン」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このGo Academyレッスンでコードを書いて実行できますか?
はい。すべてのGo Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- select文
- タイムアウトとTicker
- ファンインとファンアウトのパターン
- ワーカープールパターン