Maison >développement back-end >Golang >Pourquoi le cas d'expiration ne s'exécute-t-il pas lors de l'utilisation des canaux Go ?
Utilisation des délais d'attente avec les canaux Go
Dans Go, les goroutines et les canaux fournissent un modèle de concurrence puissant. Cependant, lors de l'utilisation de ces mécanismes, il est essentiel de gérer correctement les délais d'attente pour éviter des problèmes potentiels.
Une question courante se pose lors de l'utilisation des délais d'attente avec les canaux : pourquoi le cas de délai d'attente ne peut-il pas être exécuté ? Explorons cela et fournissons des solutions pour garantir une gestion appropriée des délais d'attente.
Code d'origine :
import "fmt" import "time" func check(u string) bool { time.Sleep(4 * time.Second) return true } func IsReachable(urls []string) bool { ch := make(chan bool, 1) for _, url := range urls { go func(u string) { select { case ch <- check(u): case <-time.After(time.Second): ch <- false } }(url) } return <-ch } func main() { fmt.Println(IsReachable([]string{"url1"})) }
Problème :
Avec ce code, toutes les URL sont toujours signalées comme accessibles, quelle que soit la connectivité réelle. Le cas d'expiration du délai d'attente n'est pas exécuté car la fonction de vérification bloque la goroutine actuelle.
Solution 1 : Exécutez la fonction de vérification dans une goroutine distincte :
Pour résoudre ce problème , déplacez la fonction de vérification dans une goroutine distincte et utilisez un autre canal pour communiquer le résultat :
package main import "fmt" import "time" func check(u string, checked chan<- bool) { time.Sleep(4 * time.Second) checked <- true } func IsReachable(urls []string) bool { ch := make(chan bool, 1) for _, url := range urls { go func(u string) { checked := make(chan bool) go check(u, checked) select { case ret := <-checked: ch <- ret case <-time.After(time.Second): ch <- false } }(url) } return <-ch } func main() { fmt.Println(IsReachable([]string{"url1"})) }
Solution 2 : démarrer un délai d'attente unique pour toutes les URL :
Alternativement, si l'objectif est de signaler l'accessibilité sur la base d'une vérification réussie, envisagez de simplifier la gestion des délais d'attente en utilisant un délai d'attente unique pour toutes les URL :
package main import "fmt" import "time" func check(u string, ch chan<- bool) { time.Sleep(4 * time.Second) ch <- true } func IsReachable(urls []string) bool { ch := make(chan bool, len(urls)) for _, url := range urls { go check(url, ch) } time.AfterFunc(time.Second, func() { ch <- false }) return <-ch } func main() { fmt.Println(IsReachable([]string{"url1", "url2"})) }
En traitant correctement la gestion des délais d'attente, les développeurs peuvent garantir que leur code Go reflète avec précision l'accessibilité des URL, offrant une expérience d'application plus fiable et cohérente.
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!