Maison >développement back-end >Golang >Comment puis-je me remettre d'une panique dans Go Goroutines ?

Comment puis-je me remettre d'une panique dans Go Goroutines ?

DDD
DDDoriginal
2024-12-13 09:01:10535parcourir

How Can I Recover from Panics in Go Goroutines?

Récupération de panique générique dans les programmes Go

Lorsque vous travaillez avec des routines Go, il peut y avoir des cas où vous souhaitez détecter et gérer les plantages ou les paniques qui s'y produisent, potentiellement pour signaler des erreurs à un serveur de rapport d'erreurs comme Sentry ou Raygun. Cependant, il est crucial de noter qu'une goroutine ne peut pas se remettre d'une panique dans une autre goroutine.

Approche idiomatique

La manière idiomatique de gérer cela est d'injecter du code dans le fonction qui est lancée en tant que goroutine. Cela implique l'utilisation d'une fonction différée qui appelle recovery(), qui offre la possibilité de se remettre d'un état de panique.

Considérez l'exemple suivant :

go func() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Caught:", r)
        }
    }()

    panic("catch me")
}()

Ce code affichera le message de panique approprié. message lors de l'exécution.

Bien qu'il soit peu pratique d'implémenter cette approche dans chaque goroutine que vous lancez, vous pouvez simplifier le processus en définissant une fonction nommée qui inclut la récupération fonctionnalité et appelez cette fonction dans votre goroutine (avec un appel différé).

func logger() {
    if r := recover(); r != nil {
        fmt.Println("Caught:", r)
    }
}

En appelant cette fonction dans une fermeture différée, vous pouvez gérer les situations de panique de manière concise.

go func() {
    defer logger()
    panic("catch me")
}()

Fonction Wrapper

Pour plus de commodité, vous pouvez créer une fonction wrapper qui prend la fonction réelle en entrée et gère le processus de récupération après panique. Cette fonction wrapper peut être utilisée comme suit :

func wrap(f func()) {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Caught:", r)
        }
    }()

    f()
}

L'utilisation de ce wrapper simplifie encore davantage le processus de gestion de la panique :

go wrap(func() {
    panic("catch me")
})

Considérations supplémentaires

Les exemples de codes fournis illustrent des situations dans lesquelles une goroutine est lancée dans la fonction wrap(). Cela permet à l'appelant de déterminer si une nouvelle goroutine est nécessaire en faisant précéder l'appel wrap() du mot-clé go. Cependant, la fonction wrap() peut également être utilisée pour protéger l'exécution de fonctions arbitraires passées en entrée, même si vous ne souhaitez pas les exécuter simultanément dans une nouvelle goroutine.

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