ホームページ > バックエンド開発 > Golang > Go の「select」ケースでチェーンされたチャネル操作がデッドロックを引き起こすのはなぜですか?

Go の「select」ケースでチェーンされたチャネル操作がデッドロックを引き起こすのはなぜですか?

Linda Hamilton
リリース: 2024-11-25 05:48:10
オリジナル
1012 人が閲覧しました

Why Do Chained Channel Operations in Go's `select` Case Cause Deadlocks?

単一選択ケースでの連鎖チャネル操作: 動作のデコード

同時および非同期プログラムの設計を追求する中で、Go の選択構造は以下を提供します。チャンネルを多重化するための強力なツールです。ただし、単一の選択ケース内で複数の操作を組み合わせると、予期しない結果が発生することがよくあります。

次のシナリオを考えてみましょう: 2 つのチャネル A と B が、異なる時間間隔 (A では 10 ミリ秒、A では 1 秒) でメッセージを送信します。 B)。 select を使用して両方のチャネルをリッスンし、受信した値をファンイン チャネルに転送します。

func main() {
    ch := fanIn(talk("A", 10), talk("B", 1000))

    for i := 0; i < 10; i++ {
        fmt.Printf("%q\n", <-ch)
    }
    fmt.Printf("Done\n")
}
ログイン後にコピー

期待される結果は次のとおりです。

"A 0"
"B 0"
"A 1"
"A 2"
"A 3"
"A 4"
"B 1"
"B 2"
"B 3"
"B 4"
Done
ログイン後にコピー

ただし、select を変更すると、連鎖チャネル操作を使用する場合:

select {
    case ch <- <-input1:
    case ch <- <-input2:
}
ログイン後にコピー

特有の現象が観察されます。動作:

"B 0"
"A 1"
"B 2"
"A 3"
"A 4"
fatal error: all goroutines are asleep - deadlock!
ログイン後にコピー

舞台裏

この動作を理解する鍵は、選択されたケース内のチャネル操作のノンブロッキングの性質にあります。一般的な選択ケースでは、非ブロッキングにできるのは 1 つのチャネル操作 (読み取りまたは書き込み) のみです。

チェーンされたチャネル操作を使用すると、1 つのケース内で複数のチャネル操作を効果的に試行することになります。最初の操作は常にブロックですが、後続の操作は非ブロックです。

変更されたコードでは、最初の操作は input1 からの値の受信をブロックします。値を受信した後、それを ch チャネルにノンブロッキングで書き込もうとします。ただし、ch チャネルの受信側が値を受け入れる準備ができていない場合、書き込み操作は失敗します。

連鎖反応

失敗した書き込み操作は、選択ケースを停止します。代わりに、現在唯一実行可能なケースである 2 番目のケースに進みます。これにより、潜在的なデッドロック シナリオが発生します。

時間の経過とともに、両方のチャネルから複数の値が受信されますが、書き込みの失敗によりファンイン チャネルに転送されなくなります。その結果、ファンイン チャネルは最終的に空になり、それ以上の値を受信できないためデッドロックが発生します。

問題の解決

この問題を回避するには、これは、選択されたケース内のチャネル操作が確実にシリアルに実行されるようにするために重要です。これは、一時変数を使用して受信した値を保存し、書き込み操作を選択ケースの外側の別のステートメントとして実行することで実現できます。

var msg string
select {
    case msg = <-input1:
    case msg = <-input2:
}

ch <- msg
ログイン後にコピー

以上がGo の「select」ケースでチェーンされたチャネル操作がデッドロックを引き起こすのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート