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 ?

Pourquoi le cas d'expiration ne s'exécute-t-il pas lors de l'utilisation des canaux Go ?

Susan Sarandon
Susan Sarandonoriginal
2024-11-10 08:19:02851parcourir

Why Does the Timeout Case Not Execute When Using Go Channels?

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!

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