Heim  >  Artikel  >  Backend-Entwicklung  >  Warum kann „recover()“ Panikattacken in Go-Routinen nicht behandeln?

Warum kann „recover()“ Panikattacken in Go-Routinen nicht behandeln?

Susan Sarandon
Susan SarandonOriginal
2024-11-06 20:01:03799Durchsuche

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

Umgang mit Panikattacken in Go-Routinen

Go-Routinen sorgen für Parallelität in Go-Programmen, aber Panikattacken innerhalb dieser Routinen können eine Herausforderung darstellen. Zur Wiederherstellung nach einer Panik wird normalerweise die Funktion „recover()“ verwendet. Es gibt jedoch Fälle, in denen „recover()“ in Goroutinen nicht wie erwartet funktioniert.

Verstehen des Wiederherstellungsfehlers in Go-Routinen

Bedenken Sie den folgenden Codeblock:

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
}

Dieser Code versucht, eine Panik in einer Goroutine mithilfe einer verzögerten Funktion in der Hauptfunktion zu beheben. Es gelingt jedoch nicht, die Panik zu beseitigen. Umgekehrt funktioniert der folgende Codeblock wie erwartet:

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
}

Behebung des Wiederherstellungsproblems

Der Schlüssel zum Verständnis dieses Verhaltens liegt in der Natur von Goroutinen. „recover()“ kann sich nur von Paniken erholen, die innerhalb derselben Goroutine auftreten, in der es aufgerufen wird. Aus dem Go-Blog:

Der Prozess wird im Stapel fortgesetzt, bis alle Funktionen in der aktuellen Goroutine zurückgekehrt sind. An diesem Punkt stürzt das Programm ab

Um mit Paniken in Goroutinen umzugehen, muss man a verwenden verzögerte Wiederherstellungsfunktion innerhalb der Goroutine selbst.

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
}

Durch die Platzierung der Wiederherstellungsfunktion innerhalb der Goroutine kann man Paniken abfangen und angemessen damit umgehen.

Das obige ist der detaillierte Inhalt vonWarum kann „recover()“ Panikattacken in Go-Routinen nicht behandeln?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn