Maison > développement back-end > Golang > Comment gérer correctement les délais d'attente avec les canaux en Go lors de la vérification de l'accessibilité des URL ?

Comment gérer correctement les délais d'attente avec les canaux en Go lors de la vérification de l'accessibilité des URL ?

Mary-Kate Olsen
Libérer: 2024-11-20 02:18:02
original
920 Les gens l'ont consulté

How to Properly Handle Timeouts with Channels in Go When Checking URL Reachability?

Gestion des délais d'attente avec les chaînes dans Go

Problème :

Lors de l'utilisation de goroutines et de chaînes pour vérifiez l'accessibilité d'une liste d'URL, la condition de timeout ne semble pas être exécutée. Cela fait que le code renvoie toujours vrai, même si certaines URL sont inaccessibles.

Analyse :

Le problème réside dans l'implémentation de la fonction check(u), qui fait que le délai d'attente ne sera jamais exécuté. Dans votre code, la fonction check(u) s'exécute dans la goroutine actuelle, bloquant l'exécution de l'instruction select dans IsReachable. Au moment où l'instruction select est débloquée, les canaux check(u) et time.After(time.Second) sont prêts à être consommés et le runtime peut choisir l'un ou l'autre.

Solution 1 :

Pour résoudre ce problème, vous pouvez exécuter la fonction check(u) dans un fichier séparé goroutine :

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(1 * time.Second):
                ch <- false
            }
        }(url)
    }
    return <-ch
}

func main() {
    fmt.Println(IsReachable([]string{"url1"}))
}
Copier après la connexion

Dans ce code modifié, la fonction check(u) est exécutée dans une goroutine et le résultat est transmis au canal vérifié. L'instruction select dans IsReachable attend désormais que le canal coché ou le canal d'expiration soit prêt. Cela garantit que la condition de délai d'attente est correctement gérée.

Solution 2 :

Vous pouvez également simplifier le code en définissant un délai d'attente unique pour toutes les URL. Cette approche est réalisable si le délai d'attente est suffisamment long par rapport au temps nécessaire pour créer des goroutines :

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"}))
}
Copier après la connexion

Dans ce code, un seul délai d'attente est défini pour toutes les URL utilisant time.AfterFunc. Si une URL est accessible dans le délai d'expiration, le canal ch recevra true et la fonction retournera true. Sinon, false sera envoyé à ch et la fonction retournera false.

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