0Pricing
Go Academy · レッスン

ワーカープールパターン

固定サイズのゴルーチンワーカープールを構築します。

「ワーカープールパターン」は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フィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. select文
  2. タイムアウトとTicker
  3. ファンインとファンアウトのパターン
  4. ワーカープールパターン
← Go Academyに戻る