ホームページ >バックエンド開発 >Golang >Go デッドロック: 「すべてのゴルーチンがスリープ状態です」エラーを回避するには?

Go デッドロック: 「すべてのゴルーチンがスリープ状態です」エラーを回避するには?

Linda Hamilton
Linda Hamiltonオリジナル
2024-12-27 13:06:18839ブラウズ

Go Deadlocks: How to Avoid the

Go のデッドロック: "スロー: すべてのゴルーチンがスリープ状態です"

ゴルーチンのデッドロックは、実行中のすべてのゴルーチンが相互に待機しているときに発生します。完了。提供された Go コードでは、チャネル ch が閉じられていないためにデッドロックが発生します。

total 関数は、範囲ループを使用して ch チャネル上の新しい値を継続的に待機します。 ch チャネルが閉じられることがないため、ループが終了することはありません。これは、この関数の実行を担当するゴルーチンが決して終了しないことを意味します。

一方、main 関数では、プログラムは ch チャネルに値を送信し、結果を受信しようとします。ただし、ゴルーチン全体が無限に待機しているため、送信された値を処理して結果を送り返すことができません。これにより、プログラムがデッドロックします。

このデッドロックを解決するには、すべての値を送信した後に ch チャネルを閉じる必要があります。これにより、新しい値の待機を停止して結果を計算するよう total 関数に信号が送られます。

チャネル クロージャーを使用したコードの修正バージョンは次のとおりです。

package main

import (
    "fmt"
)

func total(in chan int, out chan int) {
    res := 0
    for iter := range in {
        res += iter
    }
    out <- res // sends back the result
}

func main() {
    ch := make(chan int)
    rch := make(chan int)
    go total(ch, rch)
    ch <- 1
    ch <- 2
    ch <- 3
    close(ch) // this will end the loop in the total function
    result := <-rch // waits for total to give the result
    fmt.Println("Total is ", result)
}

ここで、ゴルーチンの累計が表示されます。合計を正しく実行し、結果をメインに送り返し、デッドロックを防ぎます。

以上がGo デッドロック: 「すべてのゴルーチンがスリープ状態です」エラーを回避するには?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。