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