同時実行におけるデッドロック エラー: "throw: すべての Goroutines Are Asleep"
Go で同時実行を使用する場合、すべてのゴルーチンがスリープしている場合、デッドロックが発生する可能性があります。 goroutine は相互にアクションの実行を待ちます。この問題に関連する一般的なエラーの 1 つは、「スロー: すべてのゴルーチンがスリープ中です - デッドロック!」です
問題を理解する
次の Go プログラムを考えてみましょう:
package main import ( "fmt" ) func total(ch chan int) { res := 0 for iter := range ch { res += iter } ch <- res } func main() { ch := make(chan int) go total(ch) ch <- 1 ch <- 2 ch <- 3 fmt.Println("Total is ", <-ch) }
このプログラムを実行すると、「スロー: すべてのゴルーチンがスリープ状態になっています - デッドロック!」というエラーが発生します。その理由は、ch チャネルを決して閉じないため、total 関数の範囲ループが決して終了しないためです。その結果、main 関数で結果の受信を待機しているゴルーチンは、結果を受信することはありません。
デッドロックの解決
このデッドロックを解決するには、閉じる必要があります。これ以上値が送信されないことを示す ch チャネル。さらに、別のチャネルを使用して結果を送り返すことができ、同じチャネルで直接送受信することを防ぎます。
以下の改訂されたプログラムはこれらの問題に対処しています。
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) }
閉じることでch チャネルを使用し、結果に別の rch チャネルを使用することで、デッドロックが解消され、プログラムが正しく実行できるようになります。
以上がGo の同時実行デッドロック:「すべてのゴルーチンがスリープしている」を解決する方法?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。