選択ケースでの連鎖チャネル操作: デッドロックについて
Go では、fanIn 関数は複数の入力チャネルからの値を 1 つの出力に集約しますチャネル、多重化の形式を提供します。 fanIn 関数の select ステートメントは、非ブロッキング <- 操作を使用して、複数の入力チャネルから同時に読み取ります。
ただし、select ステートメントが次のようなチェーン チャネル操作を含むように変更されている場合は、
select { case ch <- <-input1: case ch <- <-input2: }
奇妙な動作が発生する可能性があります。一部の値が削除され、デッドロックが発生する可能性があります。
これが発生する理由を理解するには、select ステートメントでは 1 つのチャネル読み取りまたは書き込み操作のみが非ブロッキングであることを覚えておくことが重要です。他のものはブロック演算子が使用されたかのように動作します。
変更された fanIn 関数では、最初のケースは input1 から値を読み取り、非ブロック的な方法で ch に書き込もうとします。 main 関数が値をすぐに消費する場合、これは成功する可能性があります。ただし、メイン関数ループがこれを実行できるほど高速ではない可能性がわずかにあります。
fanIn ループの後続の反復では、2 番目のケースが選択される可能性が高く、この時点までに、 2 番目のゴルーチンが ch に値を書き込んだ可能性があります。ただし、メイン関数が前の反復の値をまだ消費していない場合、その値は削除されます。
値を削除するこのサイクルにより、最終的にはライターが存在しないがリーダーが存在するという状況が発生します。まだ値を待っているため、デッドロックが発生します。
コードの修正バージョンは、この問題をより明確に示しています。 https://play.golang.org/p/lcM5OKx09Dj
以上がGo の「select」ステートメントでチェーンされたチャネル操作がデッドロックにつながるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。