ホームページ >バックエンド開発 >Golang >この場合、メイン コルーチンがブロックされ、デッドロックが発生するのはなぜですか?

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

PHPz
PHPz転載
2024-02-09 15:42:09626ブラウズ

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

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 までご連絡ください。