Heim > Backend-Entwicklung > Golang > Warum führt das Senden und Empfangen auf einem ungepufferten Kanal in derselben Goroutine zu einem Deadlock in Go?

Warum führt das Senden und Empfangen auf einem ungepufferten Kanal in derselben Goroutine zu einem Deadlock in Go?

Mary-Kate Olsen
Freigeben: 2024-12-23 01:20:15
Original
969 Leute haben es durchsucht

Why Does Sending and Receiving on an Unbuffered Channel in the Same Goroutine Cause a Deadlock in Go?

Deadlocks im gleichzeitigen Go verstehen: Ungepufferter Kanal innerhalb einer Goroutine

Im Parallelitätsmodell von Go sind Kanäle ein entscheidendes Werkzeug für die Kommunikation zwischen Goroutinen. Eine unsachgemäße Verwendung von Kanälen kann jedoch zu Deadlocks führen, wie in diesem Codeausschnitt dargestellt:

package main

import "fmt"

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

Bei der Ausführung führt dieser Code zu einem Deadlock mit der folgenden Fehlermeldung:

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

Warum tritt dieser Deadlock auf?

Das Problem liegt in der Verwendung eines ungepufferten Kanals innerhalb desselben Goroutine. Ungepufferte Kanäle haben keinen internen Speicher, was bedeutet, dass das Senden eines Werts an einen ungepufferten Kanal blockiert, bis eine andere Goroutine den Wert liest.

In diesem Fall sendet die Goroutine einen Wert an Kanal c und versucht, einen Wert von zu empfangen denselben Kanal nacheinander abspielen. Da es keine andere Goroutine gibt, die den Wert empfängt, bleibt die Sender-Goroutine auf unbestimmte Zeit hängen, was zu einem Deadlock führt.

Wie können Sie das Problem beheben?

Es gibt zwei Lösungen :

  1. Erstellen Sie einen gepufferten Kanal: Durch das Erstellen eines Kanals mit einem Puffer, Sie erlauben die Speicherung mehrerer Werte, bevor Sie die Absender-Goroutine blockieren. Beispiel:
c := make(chan int, 1) 
Nach dem Login kopieren

Dadurch wird ein Kanal mit einer Puffergröße von 1 erstellt, sodass ein Wert ohne Blockierung gespeichert werden kann.

  1. Verwenden Sie einen separaten Goroutine zum Senden: Anstatt innerhalb derselben Goroutine zu senden, erstellen Sie eine separate Goroutine zum Senden von Werten an den Kanal. Zum Beispiel:
package main

import "fmt"

func main() {
    c := make(chan int)    
    go func() {
        c <- 1
    }()
    fmt.Println(<-c)
}
Nach dem Login kopieren

In diesem Beispiel sendet die Sender-Goroutine asynchron einen Wert an Kanal c. Die Haupt-Goroutine empfängt dann den Wert vom Kanal, ohne dass es zu einem Deadlock kommt.

Das Verständnis des Verhaltens ungepufferter Kanäle und die Vermeidung unsachgemäßer Verwendung ist entscheidend für das Schreiben effizienter und nicht blockierender gleichzeitiger Go-Programme.

Das obige ist der detaillierte Inhalt vonWarum führt das Senden und Empfangen auf einem ungepufferten Kanal in derselben Goroutine zu einem Deadlock in Go?. 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