ホームページ >バックエンド開発 >Golang >Go の同時実行パターン。ワーカー プールとファンアウト/ファンイン

Go の同時実行パターン。ワーカー プールとファンアウト/ファンイン

DDD
DDDオリジナル
2024-10-07 22:11:01657ブラウズ

Concurrency patterns in Go; worker pools and fan-out/fan-in

Go はその優れた同時実行モデルで知られていますが、多くの開発者はゴルーチンとチャネルのみに焦点を当てています。ただし、ワーカー プールやファンアウト/ファンインなどの同時実行パターンにより、実際の効率が得られます。

この記事では、これらの高度な概念について説明し、Go アプリケーションのスループットを最大化するのに役立ちます。

同時実行性が重要な理由

同時実行性により、特に I/O 操作、Web リクエスト、バックグラウンド処理などのタスクを処理する場合、プログラムはタスクを効率的に実行できます。 Go では、ゴルーチンは何千もの同時タスクを管理するための軽量な方法を提供しますが、構造がなければボトルネックに遭遇する可能性があります。そこでワーカー プールとファンアウト/ファンイン パターンが登場します。

ワーカープール

ワーカー プールを使用すると、タスクを固定の「ワーカー」に割り当てることでゴルーチンの数を制限できます。これにより、オーバーサブスクリプションが防止され、リソース消費が削減され、タスクの実行が管理可能になります。


package main

import (
    "fmt"
    "sync"
    "time"
)

func worker(id int, jobs <-chan int, results chan<- int, wg *sync.WaitGroup) {
    defer wg.Done()
    for j := range jobs {
        fmt.Printf("Worker %d started job %d\n", id, j)
        time.Sleep(time.Second) // Simulate work
        fmt.Printf("Worker %d finished job %d\n", id, j)
        results <- j * 2
    }
}

func main() {
    jobs := make(chan int, 100)
    results := make(chan int, 100)
    var wg sync.WaitGroup

    // Start 3 workers
    for w := 1; w <= 3; w++ {
        wg.Add(1)
        go worker(w, jobs, results, &wg)
    }

    // Send jobs
    for j := 1; j <= 5; j++ {
        jobs <- j
    }
    close(jobs)

    // Wait for workers to finish
    wg.Wait()
    close(results)

    for result := range results {
        fmt.Println("Result:", result)
    }
}


この例では:

  • ジョブを同時に処理する 3 人のワーカーがいます。
  • 各ジョブはチャネル経由でワーカーに渡され、結果は処理のために収集されます。

ファンアウト/ファンイン パターン

ファンアウト/ファンイン パターンにより、複数のゴルーチンが同じタスクを処理できるようになり、ファンインでは結果が 1 つの出力に収集されます。これは、タスクを分割して結果を集計する場合に便利です。


package main

import (
    "fmt"
    "sync"
    "time"
)

func workerFanOut(id int, tasks <-chan int, wg *sync.WaitGroup) {
    defer wg.Done()
    for task := range tasks {
        fmt.Printf("Worker %d processing task %d\n", id, task)
        time.Sleep(time.Second) // Simulate work
    }
}

func main() {
    var wg sync.WaitGroup
    tasks := make(chan int, 10)

    // Fan-out: Launch multiple workers
    for i := 1; i <= 3; i++ {
        wg.Add(1)
        go workerFanOut(i, tasks, &wg)
    }

    // Send tasks
    for i := 1; i <= 9; i++ {
        tasks <- i
    }
    close(tasks)

    // Wait for workers to finish
    wg.Wait()

    fmt.Println("All tasks are processed.")
}


上記のコード内:

  • ファンアウト: タスクを同時に処理する複数のゴルーチン (ワーカー) を作成します。
  • ファンイン: 処理後、すべてのワーカーの結果を集約してさらなる処理を行うことができます。

同時実行パターンを適用して、Web サーバー、バッチ処理システム、または I/O バウンドのアプリケーションを最適化できます。ワーカー プールやファンアウト/ファンインなどのパターンを使用すると、システム容量を圧迫することなく、リソースを最適に使用できます。

知識を増やすための次のステップ:

  • これらのパターンを他の同時実行性の課題にどのように拡張できるかを検討してください。
  • リクエストを管理するワーカー プールを使用してリアルタイム Web サービスを構築します。

Go の同時実行を成功させる鍵は構造です。これらの同時実行パターンをマスターすると、Go スキルがレベルアップし、高パフォーマンスのアプリケーションを作成できるようになります。

次の投稿で Go についてさらに詳しく解説しますので、お楽しみに!

本を買って私をサポートしていただけます :)

以上がGo の同時実行パターン。ワーカー プールとファンアウト/ファンインの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。