Maison > développement back-end > Golang > Comment implémenter correctement les délais d'attente dans Go Goroutines avec les canaux ?

Comment implémenter correctement les délais d'attente dans Go Goroutines avec les canaux ?

DDD
Libérer: 2024-11-08 14:57:02
original
327 Les gens l'ont consulté

How to Implement Timeouts Correctly in Go Goroutines with Channels?

Utilisation des délais d'attente avec les canaux dans Go

Les goroutines et les canaux fournissent un mécanisme puissant pour la programmation simultanée dans Go. Cependant, la gestion des délais d'attente dans les goroutines peut être délicate.

Dans un scénario où vous souhaitez vérifier l'accessibilité d'une liste d'URL à l'aide de goroutines et d'un délai d'attente, il peut y avoir des situations où le délai d'attente n'est pas exécuté même si certaines URL ne sont pas accessibles.

Analysons le code fourni :

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

Le problème réside dans la fonction de vérification. Lorsque vous utilisez time.Sleep dans une goroutine, cela met en pause la goroutine actuelle, qui dans ce cas est la goroutine exécutant la fonction de vérification. Pendant que la fonction de vérification est en pause, l'instruction select dans la goroutine externe tentera toujours de s'exécuter.

Dans ce cas, les deux branches de l'instruction select (vérifiant le résultat ou le délai d'attente) seront exécutables après 4 secondes lorsque le chèque revient. Cependant, comme les deux branches sont exécutables, le moteur d'exécution peut choisir d'exécuter l'une ou l'autre, ce qui peut toujours renvoyer vrai.

Pour résoudre ce problème, vous devez créer une nouvelle goroutine pour chaque fonction de vérification, comme indiqué dans le code corrigé ci-dessous :

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

Dans ce cas, la fonction de vérification est exécutée dans une goroutine séparée, garantissant qu'elle ne met pas en pause la goroutine externe et que le délai d'attente peut être correctement exécuté.

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