Maison > développement back-end > Golang > Go Channels : pourquoi mon délai d'attente dans une instruction « select » ne se déclenche-t-il jamais ?

Go Channels : pourquoi mon délai d'attente dans une instruction « select » ne se déclenche-t-il jamais ?

DDD
Libérer: 2024-12-26 03:37:09
original
409 Les gens l'ont consulté

Go Channels: Why Doesn't My Timeout in a `select` Statement Ever Trigger?

Go Channels : pourquoi les délais d'attente restent non exécutés

Considérez un scénario dans lequel des goroutines et des canaux sont utilisés comme dans l'extrait de code ci-dessous. Pourquoi le scénario de délai d'attente ne se matérialise-t-il jamais ?

func main() {
    c1 := make(chan int, 1)

    go func() {
        for {
            time.Sleep(1500 * time.Millisecond)
            c1 <- 10
        }
    }()

    go func() {
        for {
            select {
            case i := <-c1:
                fmt.Println(i)
            case <-time.After(2000 * time.Millisecond):
                fmt.Println("TIMEOUT") // Not Executed
            }
        }
    }()

    fmt.Scanln()
}
Copier après la connexion

Analyse

Le scénario de délai d'attente ne se produit pas car une goroutine envoie en continu des valeurs au canal c1 environ toutes les 1,5 secondes . Le délai d'attente ne deviendrait effectif que si aucune valeur n'était reçue de c1 pendant 2 secondes.

Cependant, à la réception d'une valeur de c1, une nouvelle heure. Après l'appel est effectué lors de l'exécution de sélection suivante, générant un nouveau canal où une valeur ne sera émise qu'après 2 secondes supplémentaires. Le canal de délai d'attente de l'exécution de sélection précédente est supprimé, ce qui le rend inefficace.

Solution

Pour résoudre ce problème, le canal de délai d'attente ne doit être créé qu'une seule fois, de manière efficace :

timeout := time.After(2000 * time.Millisecond)
for {
    select {
    case i := <-c1:
        fmt.Println(i)
    case <-timeout:
        fmt.Println("TIMEOUT") // Will be printed after 2 seconds
    }
}
Copier après la connexion

Sortie

Le code modifié par la suite prints :

10
TIMEOUT
10
10
10
...
Copier après la connexion

Par conséquent, le scénario de délai d'attente est désormais exécuté avec succès après 2 secondes, reflétant le comportement prévu.

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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal