Maison >développement back-end >Golang >Pourquoi une « récupération » différée dans une fonction d'appelant ne gère-t-elle pas les paniques dans les goroutines enfants ?

Pourquoi une « récupération » différée dans une fonction d'appelant ne gère-t-elle pas les paniques dans les goroutines enfants ?

Susan Sarandon
Susan Sarandonoriginal
2024-11-03 18:06:03639parcourir

Why Doesn't a Deferred `recover` in a Caller Function Handle Panics in Child Goroutines?

Comment les fonctions d'appelant gèrent les paniques dans les goroutines enfants

On pensait auparavant qu'une panique dans une goroutine mettrait fin au programme si sa fonction d'appelant terminé avant que la panique ne survienne. Cependant, un exemple de code récent suggère le contraire :

<code class="go">func fun1() {
    fmt.Println("fun1 started")
    defer func() {
        if err := recover(); err != nil {
            fmt.Println("recover in func1")
        }
    }()

    go fun2()

    time.Sleep(10 * time.Second) // wait for the boom!
    fmt.Println("fun1 ended")
}

func fun2() {
    fmt.Println("fun2 started")

    time.Sleep(5 * time.Second)
    panic("fun2 booom!")

    fmt.Println("fun2 ended")
}</code>

Étonnamment, le programme se termine, que la fonction appelante (fun1) se termine avant ou après la panique dans la goroutine enfant (fun2). Cela soulève la question : pourquoi le mécanisme de récupération différée dans la fonction appelante n'empêche-t-il pas le programme de planter ?

Explication de la spécification

Selon la spécification Go :

"Lors de l'exécution d'une fonction F, un appel explicite à panic ou un runtime panic termine l'exécution de F. Toutes les fonctions différées par F sont ensuite exécutées comme d'habitude. Ensuite, toutes les fonctions différées exécutées par l'appelant de F sont exécutées. , et ainsi de suite jusqu'à ce que la fonction de niveau supérieur soit différée dans la goroutine en cours d'exécution. À ce stade, le programme est terminé et la condition d'erreur est signalée, y compris la valeur de l'argument de panique. Cette séquence de terminaison est appelée panique. "

Application au Code

En appliquant cette spécification à notre code, nous observons que :

  • Quand fun2 panique, il devient le goroutine de niveau supérieur et se termine.
  • Puisque fun2 ne se remet pas de la panique, le programme se termine.
  • L'appel différé dans fun1 n'est pas invoqué car la panique se produit dans une goroutine différente.

Conclusion

Par conséquent, il est crucial de comprendre qu'une goroutine ne peut pas se remettre d'une panique dans une autre goroutine. Si une goroutine enfant panique, seule la goroutine elle-même peut gérer la panique en utilisant le mécanisme de report/récupération. Si la goroutine enfant ne récupère pas, l'ensemble du programme se terminera, quel que soit le statut de son appelant.

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