Heim >Backend-Entwicklung >Golang >Warum führt die Verwendung ungepufferter Kanäle in Go zu einem Deadlock?

Warum führt die Verwendung ungepufferter Kanäle in Go zu einem Deadlock?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-12-18 16:55:10326Durchsuche

Why Does Using Unbuffered Channels in Go Lead to Deadlock?

Deadlock im Parallelitätsmodell von Go: Verwendung ungepufferter Kanäle

Im Go-Parallelitätsmodell sind Kanäle ein grundlegender Mechanismus für die Kommunikation zwischen Goroutinen . Das Verhalten von Kanälen kann jedoch je nach Puffergröße variieren. Hier befassen wir uns mit einem Deadlock-Szenario, das bei der Verwendung ungepufferter Kanäle auftritt.

Das Problem

Bedenken Sie den folgenden Go-Codeausschnitt:

package main

import "fmt"

func main() {
    c := make(chan int)    
    c <- 1   
    fmt.Println(<-c)
}

Bei der Ausführung führt dieser Code zu a Deadlock:

fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan send]:
main.main()
    /path/to/file:8 +0x52
exit status 2

Erklärung

Der Deadlock tritt aufgrund der Verwendung eines ungepufferten Kanals auf. Ein ungepufferter Kanal erfordert, wie in der Dokumentation angegeben, die Anwesenheit eines Empfängers, bevor ein Wert gesendet werden kann. In diesem Fall wird der Kanal standardmäßig als ungepuffert initialisiert (mit einer Puffergröße von 0).

Wenn die Zeile c <- 1 ausgeführt wird, versucht die Goroutine, den Wert 1 auf den Kanal zu senden. Da der Kanal jedoch keinen Puffer hat, wartet er darauf, dass ein Empfänger den Wert abruft, bevor er fortfährt.

Gleichzeitig versucht die fmt.Println(<-c)-Anweisung, einen Wert vom Kanal zu empfangen. Da jedoch noch kein Wert gesendet wurde (da die Goroutine auf einen Empfänger wartet), blockiert die Empfangsoperation.

Dies führt zu einem Deadlock, da beide Goroutinen darauf warten, dass die andere eine Operation abschließt kann ohne den anderen funktionieren.

Lösung

Um den Deadlock zu lösen, muss man einen Empfänger für den Kanal einführen. Durch die Erstellung einer separaten Goroutine für den Empfang des gesendeten Werts kann der Deadlock beseitigt werden. Der untenstehende modifizierte Code demonstriert diese Lösung:

package main

import "fmt"

func main() {
    c := make(chan int)    
    go func() {
        fmt.Println("received:", <-c)
    }()
    c <- 1   
}

Das obige ist der detaillierte Inhalt vonWarum führt die Verwendung ungepufferter Kanäle in Go 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