Heim  >  Artikel  >  Backend-Entwicklung  >  Der gepufferte Kanalbereich in Go blockiert

Der gepufferte Kanalbereich in Go blockiert

WBOY
WBOYnach vorne
2024-02-09 09:42:30690Durchsuche

Go 中缓冲通道的范围是阻塞的

php-Editor Yuzai In der Go-Sprache ist der Pufferkanal ein leistungsstarkes und flexibles Werkzeug. Gepufferte Kanäle bieten einen Mechanismus zur Synchronisierung zwischen dem Senden und Empfangen von Daten und steuern die Geschwindigkeit und Reihenfolge der Kommunikation. Sein Geltungsbereich ist blockierend, was bedeutet, dass Sende- und Empfangsvorgänge blockiert werden, bis genügend Speicherplatz oder Daten verfügbar sind, wenn der Kanal voll oder leer ist. Dieser Mechanismus kann Ressourcenkonkurrenz und Deadlock-Probleme in gleichzeitigen Programmen wirksam vermeiden und die Zuverlässigkeit und Leistung des Programms verbessern. Durch die rationelle Verwendung von Pufferkanälen können Entwickler den Ausführungsprozess gleichzeitiger Programme besser steuern und die Effizienz und Stabilität des Programms verbessern.

Frageninhalt

Mit meinem Gehirn muss etwas nicht stimmen, aber ich wurde beim Durchlaufen des Pufferkanals blockiert

    results := []search.book{}
    resultsstream := make(chan []search.book, 2)
    defer close(resultsstream)

    // parallelize searches to optimize response time
    for _, src := range sources {
        go src.search(bookname, resultsstream)
    }

    counter := 0
    for sourceresults := range resultsstream {
        counter = counter + 1
        results = append(results, sourceresults...)

        fmt.println(counter)
    }

    fmt.println("never called")

Ausgabe

1
2

Dies beweist, dass 2 Quellen den Kanal füllen (was der maximalen Kapazität entspricht). Was fehlt mir hier? never called wird, nun ja, nie aufgerufen.

Bearbeiten

    var wg sync.WaitGroup
    results := []search.Book{}
    resultsStream := make(chan []search.Book, len(sources))
    defer close(resultsStream)

    // parallelize searches to optimize response time
    for _, src := range sources {
        wg.Add(1)
        go src.Search(bookName, resultsStream, &wg)
    }

    wg.Wait()
    close(resultsStream)
    for sourceResults := range resultsStream {
        results = append(results, sourceResults...)
    }

    c.JSON(http.StatusOK, gin.H{
        "results": results,
    })

Workaround

Loop for sourceResults := range resultsStream Wiederholt Werte vom Kanal empfangen, bis er geschlossen wird. Die Schleife endet, sobald der Sender den Kanal beendet und geschlossen hat.

Sie können für jede parallele Suche einen neuen Kanal erstellen und sobald alle Worker-Coroutinen abgeschlossen sind, können Sie den Kanal schließen. Dadurch wird die Empfängerschleife beendet (Hinweis: Schließen Sie den Kanal nicht auf der Empfängerseite, da der Sender dies nicht weiß und das Senden an einen geschlossenen Kanal zu Panik führt).

Das obige ist der detaillierte Inhalt vonDer gepufferte Kanalbereich in Go blockiert. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen