前の 2 つの投稿では、Fanout と Fanin を個別に見てきました。アイテムを個別に操作したい単一のデータ ストリームがあり、並行性を使用して安全に操作できる場合、それらを一緒に使用することがよくあります。したがって、複数のワーカー スレッドにファンアウトしてから、単一のストリームにファンインします。
たとえば、大きなログ ファイルがあるとします。ファイルをいくつかのチャンクに分割し、各ワーカーがファイルの異なる部分を同時に操作して、結果を結合できるようにすることができます。
前の 2 つの投稿に従った場合、このパターンは明らかです。よくわからない場合は、上のリンクを参照してください。
シミュレートされた数値の入力ストリームを作成するProduce()関数があります。
データがなくなるまで入力チャンネル上で動作するワーカー関数があります。各値に対して入力データを「処理」し (値が奇数か偶数かを判断し)、結果の構造体を出力チャネルに送信します。
各ワーカーが完了すると、結果チャネルが閉じることに注意してください。これは、デッドロックを防ぐために必要です。そうしないと、fanin 操作が chan 上のさらなるデータを待ってスリープ状態になってしまうからです。
メインスレッドは、プロデュースから入力ストリームを取得し、多数のワーカーを起動して、各ワーカーに結果を送信する独自のチャネルを与えます。
これらの結果チャネルは、fanin オペレーションに送信されます。 fanin するには、出力を受信するチャネルを作成し、各ワーカー チャネルに対して goroutine を起動します。各ゴルーチンは、データがなくなるまでチャネルを反復処理し、終了します。 ワーカー スレッドで結果チャネルを閉じたことを思い出してください。これにより、for ループが終了できるようになります
fanin プロセスには WaitGroup を使用することに注意してください。これにより、すべての結果チャネルからのすべての結果がいつ出力チャネルに結合されたかを知ることができます。これが発生した場合、出力を消費するダウンストリーム スレッドが終了できるように、出力チャネルを閉じます。
出力チャネルにすべてのデータがあれば、メインスレッドは続行して結果を表示できます。すべてが完了するまでメインスレッドが終了しないように、ブール値チャネルを使用していることに注意してください。それ以外の場合は、プロセスが終了します。
select ステートメントを使用してファンインを行う別の方法があることに注意してください。ここで使用されるテクニックは、ワーカーの数を増減できるため、少しすっきりしています。
SIGTERM や SIGINT などによる早期終了に関しては何も対処していないことにも注意してください。これにより、もう少し複雑になります。
これをどのように実装しますか? ファンアウト/ファンイン パターンの他の実装もあります。以下にコメントやご意見を残してください?
ありがとう!
この投稿とこのシリーズのすべての投稿のコードはここにあります
以上がGo のファンアウト - ファニン パターンの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。