ホームページ >バックエンド開発 >Golang >Go の同時実行デッドロック:「すべてのゴルーチンがスリープしている」を解決する方法?

Go の同時実行デッドロック:「すべてのゴルーチンがスリープしている」を解決する方法?

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2024-12-28 13:31:13857ブラウズ

How to Resolve Go Concurrency Deadlocks:

同時実行におけるデッドロック エラー: "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 サイトの他の関連記事を参照してください。

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