Heim  >  Artikel  >  Backend-Entwicklung  >  Warum wird der Timeout-Fall bei Verwendung von Go-Kanälen nicht ausgeführt?

Warum wird der Timeout-Fall bei Verwendung von Go-Kanälen nicht ausgeführt?

Susan Sarandon
Susan SarandonOriginal
2024-11-10 08:19:02813Durchsuche

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

Timeouts mit Go-Kanälen verwenden

In Go bieten Goroutinen und Kanäle ein leistungsstarkes Parallelitätsmodell. Bei der Verwendung dieser Mechanismen ist es jedoch wichtig, Timeouts korrekt zu handhaben, um potenzielle Probleme zu vermeiden.

Bei der Verwendung von Timeouts mit Kanälen stellt sich häufig die Frage: Warum wird der Timeout-Fall möglicherweise nicht ausgeführt? Lassen Sie uns dies untersuchen und Lösungen bereitstellen, um eine ordnungsgemäße Behandlung von Zeitüberschreitungen sicherzustellen.

Originalcode:

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"}))
}

Problem:

Mit diesem Code werden alle URLs immer als erreichbar gemeldet, unabhängig von der tatsächlichen Konnektivität. Der Timeout-Fall wird nicht ausgeführt, da die Prüffunktion die aktuelle Goroutine blockiert.

Lösung 1: Führen Sie die Prüffunktion in einer separaten Goroutine aus:

Um dieses Problem zu beheben , verschieben Sie die Prüffunktion in eine separate Goroutine und verwenden Sie einen anderen Kanal, um das Ergebnis zu kommunizieren:

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"}))
}

Lösung 2: Starten Sie ein einzelnes Timeout für alle URLs:

Wenn das Ziel alternativ darin besteht, die Erreichbarkeit auf der Grundlage einer erfolgreichen Prüfung zu melden, sollten Sie erwägen, die Timeout-Verwaltung zu vereinfachen, indem Sie eine einzige Timeout-Verwaltung für alle URLs verwenden:

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"}))
}

Durch die korrekte Behandlung der Timeout-Verarbeitung können Entwickler dies sicherstellen Ihr Go-Code spiegelt die URL-Erreichbarkeit genau wider und sorgt so für ein zuverlässigeres und konsistenteres Anwendungserlebnis.

Das obige ist der detaillierte Inhalt vonWarum wird der Timeout-Fall bei Verwendung von Go-Kanälen nicht ausgeführt?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn