Maison > développement back-end > Golang > Comment puis-je prioriser l'annulation du contexte dans l'instruction « select » de Go ?

Comment puis-je prioriser l'annulation du contexte dans l'instruction « select » de Go ?

Mary-Kate Olsen
Libérer: 2024-12-08 11:45:11
original
429 Les gens l'ont consulté

How Can I Prioritize Context Cancellation in Go's `select` Statement?

Contrôle de priorité dans l'instruction Select de Go

Dans Go, l'instruction select permet une communication asynchrone entre les goroutines. Cependant, l’ordre d’évaluation des blocs de cas peut parfois conduire à des résultats inattendus. Ce problème se pose lorsque l'on tente de prioriser le traitement d'un cas spécifique, comme la sortie immédiate d'une routine lorsqu'un contexte est annulé.

Considérez le code suivant :

func sendRegularHeartbeats(ctx context.Context) {
    for {
        select {
        case <-ctx.Done():
            return
        case <-time.After(1 * time.Second):
            sendHeartbeat()
        }
    }
}
Copier après la connexion

Le Problème :
Dans ce code, l'intention est de donner la priorité à la gestion du cas ctx.Done() par rapport au cas time.After(). Cependant, en raison de l'ordre d'évaluation non déterministe de Go, le cas time.After() peut parfois être évalué en premier, conduisant à la transmission d'un battement de coeur même lorsque le contexte est annulé.

Solution :
La solution proposée dans la réponse acceptée suggère d'ajouter une instruction select imbriquée avec une vérification non bloquante pour ctx.Done(). Cependant, cela ne résout pas complètement le problème, car la probabilité que le battement de cœur soit envoyé reste élevée.

Une approche plus efficace consiste à prioriser la gestion du cas ctx.Done() en ajoutant un cas par défaut à l'instruction de sélection externe :

func sendRegularHeartbeats(ctx context.Context) {
    ticker := time.NewTicker(time.Second)
    defer ticker.Stop()

    for {
        select {
        case <-ctx.Done():
            return
        default:
        }

        select {
        case <-ctx.Done():
            return
        case <-ticker.C:
            sendHeartbeat()
        }
    }
}
Copier après la connexion

Cela garantit que le cas ctx.Done() est évalué en premier dans l'instruction de sélection externe, lui donnant une priorité plus élevée. Si le contexte est annulé, la routine reviendra immédiatement et aucun battement de cœur ne sera envoyé. Si le cas time.After() arrive en premier, il sera ignoré en raison du cas par défaut dans l'instruction de sélection externe.

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!

source:php.cn
Déclaration de ce site Web
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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal