Maison > développement back-end > Golang > Comment puis-je hiérarchiser les canaux dans l'instruction Select de Go ?

Comment puis-je hiérarchiser les canaux dans l'instruction Select de Go ?

Patricia Arquette
Libérer: 2024-12-01 09:06:14
original
372 Les gens l'ont consulté

How Can I Prioritize Channels in Go's Select Statement?

Implémentation de la priorité dans l'instruction Select de Go

L'instruction select de Go permet aux goroutines de multiplexer sur plusieurs canaux, en traitant les données du canal qui devient prêt en premier . Cependant, il ne prend pas nativement en charge la priorisation des canaux. Cet article explore un scénario de programmation courant dans lequel on souhaite donner la priorité à certains canaux par rapport à d'autres dans une instruction select.

Dans l'exemple fourni, une goroutine envoie des données à deux canaux, out et exit. Bien que les deux canaux soient initialement vides, l'intention est d'établir une priorité de telle sorte que toutes ses valeurs soient traitées avant de gérer la sortie. L'utilisation de l'instruction select standard, comme le montre la question, n'obtient pas le comportement souhaité.

Pour résoudre ce problème, Go propose une solution élégante. Au lieu de s'appuyer sur la priorisation intégrée de select, le canal qui doit être priorisé (dans ce cas, exit) ne doit être accessible qu'à la goroutine de l'expéditeur. Lorsque la goroutine de l'expéditeur est prête à se terminer, elle ferme le canal. La goroutine du récepteur, utilisant une boucle basée sur la plage pour parcourir le canal (pour x := valeurs de plage), continuera à traiter les données jusqu'à ce que le canal soit fermé.

La mise en œuvre de cette solution donne le code suivant :

package main

import (
    "fmt"
    "math/rand"
    "time"
)

var (
    produced  = 0
    processed = 0
)

func produceEndlessly(vals chan int, quit chan bool) {
    defer close(vals)
    for {
        select {
        case vals <- rand.Int():
            produced++
        case <-quit:
            return
        }
    }
}

func quitRandomly(quit chan bool) {
    d := time.Duration(rand.Int63n(5e9))
    fmt.Println("SLEEP", d)
    time.Sleep(d)
    fmt.Println("SEND QUIT")
    quit <- true
}

func main() {
    vals, quit := make(chan int, 10), make(chan bool)
    go produceEndlessly(vals, quit)
    go quitRandomly(quit)
    for x := range vals {
        fmt.Println(x)
        processed++
        time.Sleep(time.Duration(rand.Int63n(5e8)))
    }
    fmt.Println("Produced:", produced)
    fmt.Println("Processed:", processed)
}
Copier après la connexion

Dans ce code mis à jour, le canal de sortie n'est communiqué que depuis la goroutine de l'expéditeur. Cela garantit que quitter ne sera pas sélectionné tant que l'expéditeur n'est pas prêt à terminer. Par conséquent, la goroutine du récepteur épuisera toutes les données des vals avant de gérer la sortie.

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