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() } } }
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() } } }
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!