Heim  >  Artikel  >  Backend-Entwicklung  >  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
Mary-Kate OlsenOriginal
2024-10-31 04:59:02375Durchsuche

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>
<pre class="brush:php;toolbar:false">"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()

}

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

throw: all goroutines are asleep - deadlock!

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><pre class="brush:php;toolbar:false">"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()

}

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!

Stellungnahme:
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