Heim > Backend-Entwicklung > Golang > Wie kann ich Kanallesevorgänge in der „select'-Anweisung von Go priorisieren?

Wie kann ich Kanallesevorgänge in der „select'-Anweisung von Go priorisieren?

Mary-Kate Olsen
Freigeben: 2024-12-09 10:21:06
Original
802 Leute haben es durchsucht

How Can I Prioritize Channel Reads in Go's `select` Statement?

Gehe zu und wähle Problemumgehung für Anweisungspriorität aus

Stellen Sie sich das folgende Szenario vor: Sie möchten, dass eine Go-Routine zwei Kanäle überwacht und blockiert bleibt, wenn beide Kanäle blockiert sind leer. Wenn jedoch beide Kanäle Daten enthalten, priorisieren Sie die Entleerung eines Kanals vor der Adressierung des anderen.

Ursprüngliches Problem:

Im bereitgestellten Codebeispiel haben Sie einen Ausgangskanal und einen Ausgangskanal. Sie möchten, dass alle Ausgangswerte verarbeitet werden, bevor das Ausgangssignal verarbeitet wird. Die Select-Anweisung verfügt jedoch nicht über einen integrierten Prioritätsmechanismus.

Workaround-Lösung:

Go unterstützt diese Priorisierung nativ, sodass kein Workaround erforderlich ist. Die Lösung besteht darin, den Quit-Kanal nur für den Produzenten zugänglich zu machen. Wenn der Produzent fertig ist, schließt er den Beendigungskanal. Der Verbraucher liest so lange vom Out-Kanal aus, bis dieser leer ist und der Quit-Kanal geschlossen ist.

So sieht der geänderte Code aus:

package main

import (
    "fmt"
    "math/rand"
    "time"
)

var (
    produced  = 0
    processed = 0
)

func produceEndlessly(out chan int, quit chan bool) {
    defer close(out)
    for {
        select {
        case <-quit:
            fmt.Println("RECV QUIT")
            return
        default:
            out <- rand.Int()
            time.Sleep(time.Duration(rand.Int63n(5e6)))
            produced++
        }
    }
}

func main() {
    vals, quit := make(chan int, 10), make(chan bool)
    go produceEndlessly(vals, quit)
    for x := range vals {
        fmt.Println(x)
        processed++
        time.Sleep(time.Duration(rand.Int63n(5e8)))
    }
    fmt.Println("Produced:", produced)
    fmt.Println("Processed:", processed)
}
Nach dem Login kopieren

Erklärung:

Im geänderten Code hat nur die Producer-Goroutine Zugriff auf den Quit-Kanal. Wenn der Produzent fertig ist, schließt er den Beendigungskanal. Die Consumer-Goroutine liest weiter aus dem Out-Kanal, bis dieser leer ist und der Quit-Kanal geschlossen wird. Dadurch wird sichergestellt, dass alle Out-Werte verarbeitet werden, bevor der Verbraucher beendet wird.

Das obige ist der detaillierte Inhalt vonWie kann ich Kanallesevorgänge in der „select'-Anweisung von Go priorisieren?. 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
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage