Heim  >  Artikel  >  Backend-Entwicklung  >  Es liegt ein Problem mit dem Go-Kanal vor, da auf einem geschlossenen Kanal gesendet wird

Es liegt ein Problem mit dem Go-Kanal vor, da auf einem geschlossenen Kanal gesendet wird

WBOY
WBOYnach vorne
2024-02-11 18:21:081242Durchsuche

go 通道出现问题,在封闭通道上发送

php-Editor Youzi kann während des Entwicklungsprozesses mit der Go-Sprache auf einige Probleme stoßen. Eines davon ist das Problem beim Senden von Daten über einen geschlossenen Kanal. Dieses Problem kann zu Kanalblockierungen und Programmstagnation führen und den Betrieb der gesamten Anwendung beeinträchtigen. Bevor wir dieses Problem lösen können, müssen wir zunächst verstehen, was ein geschlossener Kanal ist und warum das Senden von Daten über einen geschlossenen Kanal problematisch ist. Als Nächstes werden wir uns mit diesem Problem befassen und Lösungen zur Fehlerbehebung und Optimierung unserer Go-Anwendungen bereitstellen.

Frageninhalt

Ich erhalte eine schwerwiegende Fehlermeldung: „Senden auf einem geschlossenen Kanal“ und manchmal führe ich diesen Code aus. Ich habe mehrere Lösungen ausprobiert, aber keine davon hat funktioniert. Hier ist die Darstellung des Codes, leicht zu verstehen und einfach durchzuführen Anwendungstest:

CB14CE50B218D8EAB916B15CD95527D5

Was ich möchte, ist, die Anforderungsfunktion n-mal zu starten und die erste abgeschlossene Anforderung zu erhalten, dann den Kanal zu schließen und keine weiteren Anforderungen an den Kanal zu senden. Wenn keine der Anforderungen erfolgreich abgeschlossen wird, warten Sie, bis alle Goroutinen abgeschlossen sind.

Ich vermute, das passiert, weil zwei oder mehr Goroutinen gleichzeitig prüfen, ob der Kanal geschlossen ist, und beide versuchen, in den Kanal zu schreiben, was zu einem schwerwiegenden Fehler führt.

Fehler:

goroutine 19 [running]:
main.request(0xc00000a028, 0xc00000a030, 0x0?)
        C:/test/main.go:49 +0x135
created by main.main
        C:/test/main.go:17 +0xd3
panic: send on closed channel

Kann jemand erklären, warum das passiert?

Danke im Voraus

Workaround

Das Problem liegt bei der empfangenden Goroutine (main) 过早关闭 outputCh. Eine andere Goroutine kann immer noch versuchen, darauf zu senden.

Hier ist ein anderer Weg:

package main

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

func main() {
    var wg sync.WaitGroup
    output := make(chan string)
    stop := make(chan bool)
    done := make(chan bool)

    for i := 0; i < 20; i++ {
        wg.Add(1)
        go request(output, stop, &wg)
    }

    go func() {
        wg.Wait()
        done <- true
    }()

    firstOutput := <-output
    fmt.Println("output:", firstOutput)

    fmt.Println("closing the stop channel")
    close(stop)

    <-done
    fmt.Println("end of main")
}

func request(output chan string, stop chan bool, wg *sync.WaitGroup) {
    defer wg.Done()

    fmt.Println("request started")
    time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)

    select {
    case output <- "test":
        fmt.Println("output sent")
    case <-stop:
        fmt.Println("stop channel is closed")
    }
}

Das obige ist der detaillierte Inhalt vonEs liegt ein Problem mit dem Go-Kanal vor, da auf einem geschlossenen Kanal gesendet wird. 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