ホームページ > バックエンド開発 > Golang > Go デッドロック: なぜ「スロー: すべてのゴルーチンがスリープ状態になっている」が発生するのですか?

Go デッドロック: なぜ「スロー: すべてのゴルーチンがスリープ状態になっている」が発生するのですか?

Mary-Kate Olsen
リリース: 2025-01-02 15:03:39
オリジナル
558 人が閲覧しました

Go Deadlock: Why Does

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

Go プログラムでは、2 つ以上のゴルーチンが待機しているときにデッドロックが発生しますお互いが終了するのを待って、結果的に先に進むことができないフリーズ状態になります。この問題は、「スロー: すべてのゴルーチンがスリープ中 - デッドロック!」として報告されることがよくあります

このデッドロックが発生する理由を理解するために、簡略化された 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)
}
ログイン後にコピー

このプログラムでは、 total 関数は、ch チャネル経由で送信された数値の合計を計算し、結果を同じチャネルに送り返します。デッドロックは、次の条件が満たされるために発生します:

  • for ループ内の関数ブロックの合計が ch (range キーワードを使用) 経由のさらなる入力を待機しています。
  • メイン関数は送信します。 3 つの値を ch に送信しますが、チャネルは閉じません。
  • total 関数はまださらなる入力を待っているため、結果は送信されません。 ch.
  • main 関数は、fmt.Println 行で ch.

からの結果を待っています。これにより、両方のゴルーチン (実行中の合計とmain) は他のゴルーチンが動作するのを待っているため、「スロー: すべてのゴルーチンがスリープ状態です」エラーが発生します。

これを解決するにはデッドロックが発生した場合は、最後の値を送信した後に main 関数で ch チャネルを閉じることができます。

ch <- 3
close(ch)
ログイン後にコピー

チャネルを閉じると、入力がもうないという信号が合計 goroutine に送信され、計算を完了して送信できるようになります。結果はchに返されます

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

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