Go プログラムで「致命的エラー: すべてのゴルーチンがスリープ中 - デッドロック!」が発生するのはなぜですか?また、それはどのように修正できるのでしょうか?

Patricia Arquette
リリース: 2024-11-17 02:23:03
オリジナル
164 人が閲覧しました

Why do Go programs encounter the

Go: デッドロック パニック - 原因の理解と修正

Go で発生する一般的なエラーは、「致命的なエラー: すべてのゴルーチンが眠っている - デッドロック!」 goroutine 間の通信を管理しようとするとき。このエラーは、ゴルーチンが互いに続行を待機している状態でスタックした場合に発生します。

問題ステートメント

読み取り対象となる次のコードを考えてみましょう。テキスト ファイルから単語の行を抽出し、チャネルに保存して、個別に出力します。

func main() {
    f, _ := os.Open("D:\input1.txt")
    scanner := bufio.NewScanner(f)
    file1chan := make(chan string)
    for scanner.Scan() {
        line := scanner.Text()
        parts := strings.Fields(line)
        for i := range parts {
            file1chan <- parts[i]
        }
    }
    print(file1chan)
}

func print(in <-chan string) {
    for str := range in {
        fmt.Printf("%s\n", str)
    }
}
ログイン後にコピー

デッドロックの原因

このコードを実行すると、デッドロック エラーが発生します。これは、チャネル file1chan がバッファリングされていないために発生します。その結果、チャネルに値を送信しようとすると、チャネルは無限にブロックされ、受信者を待ちます。

デッドロックの修正

デッドロックを解決するには、 2 つのオプションがあります:

  1. バッファリングされたチャネルを使用する:
    make(chan) の 2 番目の引数としてサイズを指定することで、バッファリングされたチャネルを作成できます。

    file1chan := make(chan string, 1) // buffer size of one
    ログイン後にコピー

    バッファリングされたチャネルは配列のように機能し、チャネルに利用可能な容量がある場合、送信者はブロックせずに値を送信できます。

  2. 新しいゴルーチンを使用する:
    バッファされていないチャネルに値を送信するために新しいゴルーチンを開始できます:

    file1chan := make(chan string)
    go func() { // start a new goroutine that sends strings down file1chan
        for scanner.Scan() {
            line := scanner.Text()
            parts := strings.Fields(line)
            for i := range parts {
                file1chan <- parts[i]
            }
        }
        close(file1chan)
    }()
    
    print(file1chan)
    ログイン後にコピー

    このアプローチでは、新しいゴルーチンが値を送信する責任を負います。メインのゴルーチンはそれらを出力することに重点を置いています。

これらのソリューションのいずれかを実装すると、デッドロックが効果的に排除され、ゴルーチン間のスムーズな通信が可能になります。

以上がGo プログラムで「致命的エラー: すべてのゴルーチンがスリープ中 - デッドロック!」が発生するのはなぜですか?また、それはどのように修正できるのでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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