Go Academy · レッスン

パイプラインのステージ

チャネルのステージを連結します

レッスン 3/413 ステップ

「パイプラインのステージ」はCoddyKit上の無料Go Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはGo Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Go Academyコースには全4レッスンが含まれています。

パイプラインとは

パイプラインとは、チャネルで接続された一連のステージです。各ステージは値を受け取り、処理を行い、結果を下流へ送信します。データは組立ラインのように流れます。

  • 各ステージは goroutine です
  • ステージ間の通信にはチャネルだけを使用します
  • 組み合わせやすく、動作を理解しやすい構成です

ステージのシグネチャ規約

一般的に各ステージは、1つ以上の受信専用入力チャネルを受け取り、受信専用出力チャネルを返します。これにより、ステージを連結できます。

func stage(in <-chan int) <-chan int {
    out := make(chan int)
    go func() {
        defer close(out)
        for v := range in {
            out <- v
        }
    }()
    return out
}

ソースステージ

最初のステージがデータを生成します。スライスまたは可変長引数を受け取り、それらをチャネルへストリーム配信することがよくあります。

func numbers(vals ...int) <-chan int {
    out := make(chan int)
    go func() {
        defer close(out)
        for _, v := range vals {
            out <- v
        }
    }()
    return out
}

変換ステージ

このステージはすべての値に10を掛けます。in から読み取り、変換した値を out に書き込みます。

func tenfold(in <-chan int) <-chan int {
    out := make(chan int)
    go func() {
        defer close(out)
        for v := range in {
            out <- v * 10
        }
    }()
    return out
}

フィルターステージ

フィルターは、条件を満たす値だけを転送します。ここでは偶数を残し、それ以外を破棄します。

func evens(in <-chan int) <-chan int {
    out := make(chan int)
    go func() {
        defer close(out)
        for v := range in {
            if v%2 == 0 {
                out <- v
            }
        }
    }()
    return out
}

ステージの連結

あるステージの出力を次のステージの入力として渡すことで、ステージを組み合わせます。連結した処理は、ほとんど文章のように読めます。

pipe := tenfold(evens(numbers(1, 2, 3, 4)))
for v := range pipe {
    fmt.Println(v)
}

defer close(out)

defer close(out) を使うと、後から早期リターンを追加した場合でも、ステージの goroutine が戻るときに出力チャネルが必ず閉じられます。これにより、ストリームの終了シグナルが下流へ伝わります。

完全なパイプライン

ソース、フィルター、変換の順に処理します。実行して、偶数の入力を10倍した値だけが出力されることを確認しましょう。

package main

import "fmt"

func numbers(vals ...int) <-chan int {
    out := make(chan int)
    go func() { defer close(out); for _, v := range vals { out <- v } }()
    return out
}

func evens(in <-chan int) <-chan int {
    out := make(chan int)
    go func() { defer close(out); for v := range in { if v%2 == 0 { out <- v } } }()
    return out
}

func tenfold(in <-chan int) <-chan int {
    out := make(chan int)
    go func() { defer close(out); for v := range in { out <- v * 10 } }()
    return out
}

func main() {
    for v := range tenfold(evens(numbers(1, 2, 3, 4, 5, 6))) {
        fmt.Println(v)
    }
}

バッチ処理ではなくストリーミング

値は生成されると、1つずつパイプラインを流れます。変換ステージは、ソースが最後の項目を出力する前に、最初の項目の処理を開始できます。これにより、メモリ使用量とレイテンシを抑えられます。

パイプラインは遅延実行されます

ステージは、その出力から何かが読み取られるまで処理を行いません。コンシューマーが range を使った読み取りを途中で止めると、上流のステージは送信時にブロックします。この自然なバックプレッシャーにより、不要な計算を防げます。

並行性の追加

遅いステージを高速化するには、同じ入力を読み取る複数のインスタンスにファンアウトし、その出力を統合します。ステージのシグネチャは変わらず、配線だけが変わります。

クイックチェック

パイプラインについての理解度を確認しましょう。

まとめ

パイプラインのステージについて学びました。

  • 各ステージは受信専用入力を受け取り、受信専用出力を返します
  • defer close(out) によってストリームの終了が伝わります
  • 呼び出しをネストしてステージを連結します
  • パイプラインはバックプレッシャーを伴って遅延ストリーミングします
無料で開始

AI チューターと学ぶ Go — 無料

ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。

コース
51
レッスン
203

よくある質問

「パイプラインのステージ」レッスンは無料ですか?

はい。「パイプラインのステージ」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Go Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Go Academyコースには全4レッスンが含まれています。

「パイプラインのステージ」で何を学びますか?

チャネルのステージを連結します ブラウザで直接実行するハンズオンコードでGo Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Go Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのGo Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「パイプラインのステージ」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このGo Academyレッスンでコードを書いて実行できますか?

はい。すべてのGo Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

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

  1. ワーカープールパターン
  2. Fan-OutとFan-In
  3. パイプラインのステージ
  4. グレースフルシャットダウン
← Go Academyに戻る