Warum führt die Übergabe von Werten anstelle von Zeigern zu einem Deadlock in Go-Kanälen?

Barbara Streisand
Freigeben: 2024-10-28 21:44:02
Original
296 Leute haben es durchsucht

Why Does Passing Values Instead of Pointers Cause Deadlock in Go Channels?

Deadlock-Fehler im Go-Kanal

In Go stellen Kanäle ein Kommunikationsmittel zwischen Goroutinen dar. Die unsachgemäße Verwendung von Kanälen kann jedoch zu Deadlocks führen, bei denen Goroutinen auf unbestimmte Zeit blockiert werden.

Eine häufige Ursache für Deadlocks bei Kanälen ist die Übergabe von Werttypen anstelle von Zeigern in Goroutine-Funktionen. Dies liegt daran, dass Go Werttypen nach Wert übergibt, was bedeutet, dass eine Kopie des Werts erstellt wird.

Betrachten Sie dieses Beispiel:

<code class="go">import (
    "fmt"
    "sync"
)

func push(c chan int, wg sync.WaitGroup) {
    for i := 0; i < 5; i++ {
        c <- i
    }
    wg.Done()
}

func pull(c chan int, wg sync.WaitGroup) {
    for i := 0; i < 5; i++ {
        result, ok := <-c
        fmt.Println(result, ok)
    }
    wg.Done()
}

func main() {
    var wg sync.WaitGroup
    wg.Add(2)
    c := make(chan int)

    go push(c, wg)
    go pull(c, wg)

    wg.Wait()
}</code>
Nach dem Login kopieren

Das Ausführen des Programms führt zu einem Deadlock-Fehler:

    0 true
    1 true
    2 true
    3 true
    4 true
    throw: all goroutines are asleep - deadlock!
Nach dem Login kopieren

Der Deadlock tritt auf, weil die WaitGroup als Wert an die Push- und Pull-Funktionen übergeben wird. Wenn die WaitGroup in einer der Goroutinen aktualisiert wird, werden die Änderungen nicht in der anderen Goroutine widergespiegelt, da diese über eine Kopie des Werts verfügt.

Um den Deadlock aufzulösen, müssen wir die WaitGroup als Zeiger übergeben. Dadurch wird sichergestellt, dass beide Goroutinen auf derselben Instanz der WaitGroup ausgeführt werden.

Hier ist die korrigierte Version des Codes:

<code class="go">import (
    "fmt"
    "sync"
)

func push(c chan int, wg *sync.WaitGroup) {
    for i := 0; i < 5; i++ {
        c <- i
    }
    wg.Done()
}

func pull(c chan int, wg *sync.WaitGroup) {
    for i := 0; i < 5; i++ {
        result, ok := <-c
        fmt.Println(result, ok)
    }
    wg.Done()
}

func main() {
    var wg sync.WaitGroup
    wg.Add(2)
    c := make(chan int)

    go push(c, &wg)
    go pull(c, &wg)

    wg.Wait()
}</code>
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonWarum führt die Übergabe von Werten anstelle von Zeigern zu einem Deadlock in Go-Kanälen?. 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
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!