この場合、メイン コルーチンがブロックされ、デッドロックが発生するのはなぜですか?

PHPz
リリース: 2024-02-09 15:42:09
転載
607 人が閲覧しました

この場合、メイン コルーチンがブロックされ、デッドロックが発生するのはなぜですか?

PHP では、メイン コルーチンがブロックされ、デッドロックが発生することがよくあります。メイン コルーチンの実行中に、ネットワーク リクエスト、IO 操作、他のコルーチンの結果の待機などのブロック操作が発生した場合、適切な処理方法がないとデッドロックが発生する可能性があります。この場合、メイン コルーチンは実行を継続できず、他のコルーチンも実行の機会を得ることができず、プログラム全体がデッドロックに陥ります。では、なぜこの場合メイン コルーチンがブロックされ、デッドロックが発生するのでしょうか?以下でこれに答えてみましょう。

質問内容

package main

import "fmt"

func square(numbers chan int, squares chan int) {
    for n := range numbers {
        squares <- n * n
    }
    close(squares)
}

func main() {
    numbers := make(chan int)
    squares := make(chan int)

    go square(numbers, squares)

    for i := 0; i < 10; i++ {
        numbers <- i
    }
    close(numbers)

    for s := range squares {
        fmt.Println(s)
    }
}
ログイン後にコピー

つまり、このコードが機能するには、次のような別の goroutine で numbers チャネルに数値を送信する必要があることはわかっています。 リーリー

そうは言っても、なぜデッドロックが発生するのかを説明するのは難しいと思います。スケジューラーが実行順序を保証しないことはよく知っています。ただし、ループ内の

numbers チャネルに初めて送信すると、メインの goroutine はブロックされますが、その後、スケジューラが square goroutine の実行を開始し、その後通信を繰り返す可能性があります。次に、そうではありませんか?

回避策

メインの goroutine がブロックされる理由は、この場合、データを squares チャネルに送信した後、squares チャネルから値をまったく読み取らないためです。

numbers を実行すると、go square ゴルーチンは値を受け取り、squares チャネルに送信します。ただし、同時に、メインの Goroutine はまだ Numbers チャネルにデータを送信しているため、メインの Goroutine は sqaures チャネルから値を受け取りません。

これは、メイン コルーチンがこの行

for s := range squares を決して実行しないことを意味し、デッドロックが発生します。

このコードを正しく実行するには、以下に示すように変更します。

リーリー

以上がこの場合、メイン コルーチンがブロックされ、デッドロックが発生するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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