ホームページ  >  記事  >  バックエンド開発  >  Go で「致命的なエラー: すべてのゴルーチンがスリープ中 - デッドロック」を修正する方法は?

Go で「致命的なエラー: すべてのゴルーチンがスリープ中 - デッドロック」を修正する方法は?

DDD
DDDオリジナル
2024-11-18 07:41:02698ブラウズ

How to Fix

Go: 「致命的なエラー: すべてのゴルーチンがスリープ状態 - デッドロック」の理解と解決

Go プログラムを実行すると、エラー メッセージが表示される「致命的エラー: すべてのゴルーチンがスリープ中 - デッドロック」は、プログラムのすべてのゴルーチン (軽量スレッド) が無期限にブロックされ、デッドロックが発生することを示します。

提供されたコードでは、バッファリングされていない性質により、この問題が発生します。 「file1chan」チャンネル。バッファリングされていないチャネルに値が送信されると、それを受信する準備ができているゴルーチンが他にない場合はブロックされます。この場合、メインの goroutine は値を「file1chan」に送信し、同時に goroutine が受信することはありません。そのため、デッドロックが発生します。

解決策 1: 同時実行パターンを導入する

デッドロックを解決するには、「file1chan」から値を受け取り、メインのゴルーチンのブロックを回避する別個の並行ゴルーチンを導入します。以下の goroutine アプローチで変更されたコード:

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

解決策 2: バッファリングされたチャネルを使用する

代わりに、バッファリングされたチャネルを使用して固定数を処理することもできます。デッドロックを引き起こさずに値の調整を行います。このタスクには、容量 1 のバッファリングされたチャネルで十分です。

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

バッファリングされたチャネルを使用すると、受信側の準備がまだ整っていない場合でも送信側は実行を継続できるため、デッドロックが回避されます。

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

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