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
DDDoriginal
2024-12-26 03:37:09404parcourir

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

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
    }
}

Sortie

Le code modifié par la suite prints :

10
TIMEOUT
10
10
10
...

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!

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