Heim > Backend-Entwicklung > Golang > Warum führt die Übergabe einer WaitGroup als Wert in Go-Kanälen zu einem Deadlock?

Warum führt die Übergabe einer WaitGroup als Wert in Go-Kanälen zu einem Deadlock?

Mary-Kate Olsen
Freigeben: 2024-10-31 04:59:02
Original
485 Leute haben es durchsucht

Why does passing a WaitGroup by value in Go channels lead to a deadlock?

Deadlock im Go-Kanal aufgrund der Referenzübergabe

In Go sind Kanäle ein leistungsstarker Kommunikationsmechanismus, aber wenn nicht, können sie zu Deadlocks führen richtig verwendet. Ein Deadlock tritt auf, wenn zwei oder mehr Goroutinen aufeinander warten, um einen Vorgang abzuschließen, was dazu führt, dass keine Goroutine fortfahren kann.

Betrachten Sie das folgende Go-Programm:

<br>Pakethauptseite</p>
<p>import (</p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">"fmt"
"sync"
Nach dem Login kopieren
Nach dem Login kopieren

)

func push(c chan int, wg sync.WaitGroup) {

for i := 0; i < 5; i++ {
    c <- i
}
wg.Done()
Nach dem Login kopieren
Nach dem Login kopieren

}

func pull(c chan int, wg sync.WaitGroup) {

for i := 0; i < 5; i++ {
    result, ok := <-c
    fmt.Println(result, ok)
}
wg.Done()
Nach dem Login kopieren
Nach dem Login kopieren

}

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

}

Wenn Sie dieses Programm ausführen, gerät es in Panik mit einem Deadlock-Fehler:

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

Das Problem liegt darin, wie die WaitGroup an die Goroutinen übergeben wird . In Go werden Strukturen als Wert übergeben, was bedeutet, dass eine Kopie der WaitGroup an jede Goroutine übergeben wird. Wenn eine Goroutine „Done“ für ihre Kopie aufruft, hat dies keine Auswirkungen auf die ursprüngliche WaitGroup, die in der Hauptfunktion erstellt wurde.

Um den Deadlock zu beheben, muss der WaitGroup-Zeiger anstelle des Werts übergeben werden. Hier ist der korrigierte Code:

<br>package main</p><p>import (</p><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">"fmt"
"sync"
Nach dem Login kopieren
Nach dem Login kopieren

)

func push(c chan int , wg *sync.WaitGroup) {

for i := 0; i < 5; i++ {
    c <- i
}
wg.Done()
Nach dem Login kopieren
Nach dem Login kopieren

}

func pull(c chan int, wg *sync.WaitGroup) {

for i := 0; i < 5; i++ {
    result, ok := <-c
    fmt.Println(result, ok)
}
wg.Done()
Nach dem Login kopieren
Nach dem Login kopieren

}

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 die Übergabe des WaitGroup-Zeigers anstelle des Werts haben beide Goroutinen Zugriff auf denselben WaitGroup-Instanz. Wenn eine Goroutine „Done“ aufruft, verringert sie die Anzahl der ursprünglichen WaitGroup, sodass die andere Goroutine fortfahren kann.

Das obige ist der detaillierte Inhalt vonWarum führt die Übergabe einer WaitGroup als Wert in Go-Kanälen zu einem Deadlock?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Vorheriger Artikel:Wie kann man in Golang eine For-Schleife von außerhalb ihres Geltungsbereichs unterbrechen? Nächster Artikel:Warum können Methoden auf „T“ von „*T“ in Go nicht verwendet werden?
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
Aktuelle Ausgaben
verwandte Themen
Mehr>
Beliebte Empfehlungen
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage