Heim > Backend-Entwicklung > Golang > Go-Kanäle: Warum wird mein Timeout in einer „select'-Anweisung nie ausgelöst?

Go-Kanäle: Warum wird mein Timeout in einer „select'-Anweisung nie ausgelöst?

DDD
Freigeben: 2024-12-26 03:37:09
Original
404 Leute haben es durchsucht

Go Channels: Why Doesn't My Timeout in a `select` Statement Ever Trigger?

Go-Kanäle: Warum Zeitüberschreitungen nicht ausgeführt werden

Stellen Sie sich ein Szenario vor, in dem Goroutinen und Kanäle wie im folgenden Codeausschnitt verwendet werden. Warum tritt das Timeout-Szenario nie ein?

func main() {
    c1 := make(chan int, 1)

    go func() {
        for {
            time.Sleep(1500 * time.Millisecond)
            c1 <- 10
        }
    }()

    go func() {
        for {
            select {
            case i := <-c1:
                fmt.Println(i)
            case <-time.After(2000 * time.Millisecond):
                fmt.Println("TIMEOUT") // Not Executed
            }
        }
    }()

    fmt.Scanln()
}
Nach dem Login kopieren

Analyse

Das Timeout-Szenario tritt nicht ein, da eine Goroutine kontinuierlich etwa alle 1,5 Sekunden Werte an den c1-Kanal sendet . Das Timeout würde nur wirksam, wenn 2 Sekunden lang keine Werte von c1 empfangen würden.

Bei Empfang eines Werts von c1 wird jedoch ein neuer Time.After-Aufruf in der anschließenden Select-Ausführung durchgeführt, wodurch ein neuer Kanal generiert wird wobei ein Wert erst nach weiteren 2 Sekunden ausgegeben wird. Der Timeout-Kanal aus der vorherigen Select-Ausführung wird verworfen, wodurch er unwirksam wird.

Lösung

Um dieses Problem zu beheben, sollte der Timeout-Kanal nur einmal erstellt werden, und zwar effektiv:

timeout := time.After(2000 * time.Millisecond)
for {
    select {
    case i := <-c1:
        fmt.Println(i)
    case <-timeout:
        fmt.Println("TIMEOUT") // Will be printed after 2 seconds
    }
}
Nach dem Login kopieren

Ausgabe

Der geänderte Code anschließend druckt:

10
TIMEOUT
10
10
10
...
Nach dem Login kopieren

Daher wird das Timeout-Szenario nun nach 2 Sekunden erfolgreich ausgeführt und spiegelt das beabsichtigte Verhalten wider.

Das obige ist der detaillierte Inhalt vonGo-Kanäle: Warum wird mein Timeout in einer „select'-Anweisung nie ausgelöst?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
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
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage