ホームページ  >  記事  >  バックエンド開発  >  別々の Go ルーチンでパニックに対処する方法は?

別々の Go ルーチンでパニックに対処する方法は?

DDD
DDDオリジナル
2024-11-07 20:36:02368ブラウズ

How to Handle Panics in Separate Go Routines?

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

Go ルーチンでパニックが発生した場合、適切に処理することが重要です。回復関数を使用すると、パニック値を効果的に取得し、それに応じて処理できます。

一般的なアプローチの 1 つは、遅延関数を使用して 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")
        }
    }()

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

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

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

パニックはゴルーチン内のハンドル関数で発生しますが、 main 関数の遅延リカバリ関数はそれをキャプチャできません。これは、リカバリは、パニックが発生した同じ goroutine で呼び出された場合にのみ機能するためです。

この問題を解決するには、遅延リカバリ関数呼び出しをハンドル関数内に移動します。

func main() {
    done := make(chan int64)
    defer fmt.Println("Graceful End of program")

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

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

    var a *int64
    a = nil

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

これにより、変更により、ハンドル関数でパニックが発生すると、同じゴルーチン内の遅延回復関数がそれをキャッチし、それに応じて処理します。

以上が別々の Go ルーチンでパニックに対処する方法は?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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