Heim > Backend-Entwicklung > Golang > Wie behebe ich Deadlock-Fehler in Go-Kanälen bei Verwendung von sync.WaitGroup?

Wie behebe ich Deadlock-Fehler in Go-Kanälen bei Verwendung von sync.WaitGroup?

Patricia Arquette
Freigeben: 2024-10-29 02:36:02
Original
490 Leute haben es durchsucht

How to Fix Deadlock Errors in Go Channels When Using sync.WaitGroup?

Deadlock-Fehler in Go-Kanälen verstehen

In diesem Artikel analysieren wir die Ursachen hinter dem „Deadlock“! Fehler, der aus einer Deadlock-Situation mit Go-Kanälen im folgenden Codeausschnitt entsteht:

package main

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()
}
Nach dem Login kopieren

Beim Ausführen dieses Codes tritt der folgende Fehler auf:

throw: all goroutines are asleep - deadlock!
Nach dem Login kopieren

Verstehen des Deadlocks

Der Deadlock tritt auf, weil Strukturen, wie die sync.WaitGroup in diesem Code, als Wert und nicht als Referenz übergeben werden. Das bedeutet, dass wir, wenn wir die WaitGroup an unsere Funktionen übergeben (Push und Pull), tatsächlich eine Kopie der WaitGroup anstelle des ursprünglichen Objekts übergeben.

Infolgedessen arbeitet jede Funktion an ihrer eigenen Kopie der WaitGroup, und wenn sie wg.Done() aufrufen, dekrementieren sie ihre eigenen Kopien. Dadurch wird die ursprüngliche WaitGroup, auf die unsere Haupt-Goroutine wartet, nicht aktualisiert, was zu einem Deadlock führt.

Deadlock beheben

Um dieses Problem zu beheben, müssen wir den Zeiger übergeben zur WaitGroup anstelle des Werts. Dadurch wird sichergestellt, dass sowohl die Push- als auch die Pull-Funktion auf derselben Instanz der WaitGroup arbeiten und ihre Aufrufe von wg.Done() sich auf das ursprüngliche Objekt auswirken.

Hier ist eine korrigierte Version des Codes:

package main

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()
}
Nach dem Login kopieren

Durch diese Änderung übergeben wir nun den Zeiger auf die WaitGroup an unsere Funktionen und stellen so sicher, dass beide am selben Objekt arbeiten und dessen Status korrekt aktualisieren. Dadurch wird die Deadlock-Situation beseitigt und unser Programm kann fehlerfrei ausgeführt werden.

Das obige ist der detaillierte Inhalt vonWie behebe ich Deadlock-Fehler in Go-Kanälen bei Verwendung von sync.WaitGroup?. 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