ホームページ >バックエンド開発 >Golang >Go ルーチンで「recover()」がパニックを処理できないのはなぜですか?

Go ルーチンで「recover()」がパニックを処理できないのはなぜですか?

Susan Sarandon
Susan Sarandonオリジナル
2024-11-06 20:01:03882ブラウズ

Why Does `recover()` Fail to Handle Panics in Go Routines?

Go ルーチンでのパニックの処理

Go ルーチンは Go プログラムで同時実行性を提供しますが、これらのルーチン内でパニックが発生すると課題が生じる可能性があります。パニックから回復するには、通常、recover() 関数が使用されます。ただし、ゴルーチン内で、recover() が期待どおりに動作しない場合があります。

Go ルーチンでのリカバリの失敗を理解する

次のコード ブロックを考えてみましょう。

func main() {
    done := make(chan int64)
    defer fmt.Println("Graceful End of program")
    defer func() {
     r := recover()
     if _, ok := r.(error); ok {
        fmt.Println("Recovered")
     }
    }()

    go handle(done)
    for {
        select{
        case <- done:
        return
        }
    } 
}

func handle(done chan int64) {
    var a *int64
    a = nil

    fmt.Println(*a)
    done <- *a
}

このコードは、main 関数の遅延関数を使用して、ゴルーチンのパニックから回復しようとします。しかし、パニック状態を回復することはできません。逆に、次のコード ブロックは期待どおりに動作します。

func main() {
    done := make(chan int64)
    defer fmt.Println("Graceful End of program")
    defer func() {
     r := recover()
     if _, ok := r.(error); ok {
        fmt.Println("Recovered")
     }
    }()

    handle(done)
    for {
        select{
        case <- done:
        return
        }
    } 
}

func handle(done chan int64) {
    var a *int64
    a = nil

    fmt.Println(*a)
    done <- *a
}

リカバリの問題の解決

この動作を理解する鍵は、ゴルーチンの性質にあります。 reverse() は、それが呼び出された同じ goroutine 内で発生したパニックからのみ回復できます。 Go ブログより:

現在のゴルーチン内のすべての関数が戻るまでプロセスはスタックを上っていき、その時点でプログラムはクラッシュします

ゴルーチンでパニックを処理するには、

func handle(done chan int64) {
    defer func() {
        if r := recover(); r != nil {
            if _, ok := r.(error); ok {
                fmt.Println("Recovered in goroutine")
            }
        }
    }()

    var a *int64
    a = nil

    fmt.Println(*a)
    done <- *a
}

ゴルーチン内に回復関数を配置することで、パニックを遮断し、適切に処理できます。

以上がGo ルーチンで「recover()」がパニックを処理できないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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