Maison  >  Article  >  développement back-end  >  Pourquoi `recover()` ne parvient-il pas à gérer les paniques dans les routines Go ?

Pourquoi `recover()` ne parvient-il pas à gérer les paniques dans les routines Go ?

Susan Sarandon
Susan Sarandonoriginal
2024-11-06 20:01:03799parcourir

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

Gestion des paniques dans les routines Go

Les routines Go assurent la simultanéité dans les programmes Go, mais les paniques au sein de ces routines peuvent poser des défis. Pour récupérer des paniques, la fonction recovery() est généralement utilisée. Cependant, il existe des cas où recovery() ne fonctionne pas comme prévu dans les goroutines.

Comprendre l'échec de la récupération dans les routines Go

Considérez le bloc de code suivant :

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
}

Ce code tente de se remettre d'une panique dans une goroutine en utilisant une fonction différée dans la fonction principale. Cependant, il ne parvient pas à récupérer la panique. À l'inverse, le bloc de code suivant fonctionne comme prévu :

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
}

Résoudre le problème de récupération

La clé pour comprendre ce comportement réside dans la nature des goroutines. recovery() ne peut récupérer que des paniques qui se produisent dans la même goroutine où elle est appelée. Depuis le blog Go :

Le processus continue dans la pile jusqu'à ce que toutes les fonctions de la goroutine actuelle soient revenues, moment auquel le programme plante

Pour gérer les paniques dans les goroutines, il faut utiliser un fonction de récupération différée au sein de la goroutine elle-même.

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
}

En plaçant la fonction de récupération dans la goroutine, on peut intercepter les paniques et les gérer de manière appropriée.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn