Heim > Backend-Entwicklung > Golang > Warum verursachen Go-Kanäle Deadlocks und wie können wir sie verhindern?

Warum verursachen Go-Kanäle Deadlocks und wie können wir sie verhindern?

Mary-Kate Olsen
Freigeben: 2024-11-02 09:50:03
Original
490 Leute haben es durchsucht

Why Do Go Channels Cause Deadlocks and How Can We Prevent Them?

Go-Kanäle und Deadlocks: Das Blockierungsproblem verstehen

Bei der Arbeit mit Go-Kanälen kann es zu Deadlocks kommen, wenn keine ordnungsgemäße Synchronisierung gewährleistet ist. Betrachten Sie das folgende Beispiel:

<code class="go">func main() {
    c1 := make(chan int)
    c2 := make(chan int)

    // Create two goroutines that ping-pong values between channels
    go func() {
        for i := range c1 {
            println("G1 got", i)
            c2 <- i
        }
    }()

    go func() {
        for i := range c2 {
            println("G2 got", i)
            c1 <- i
        }
    }()

    // Send an initial value to start the chain
    c1 <- 1

    // Wait for a long time to observe the ping-ponging behavior
    time.Sleep(1000000000 * 50)
}</code>
Nach dem Login kopieren

Dieser Code gibt Werte auf unbestimmte Zeit erfolgreich aus, bis die Hauptfunktion beendet wird. Wenn jedoch ein anderer Wert an einen der Kanäle gesendet wird, kommt es zu einem Deadlock:

<code class="go">func main() {
    c1 := make(chan int)
    c2 := make(chan int)

    // Create two goroutines to ping-pong values between channels
    go func() {
        for i := range c1 {
            println("G1 got", i)
            c2 <- i
        }
    }()

    go func() {
        for i := range c2 {
            println("G2 got", i)
            c1 <- i
        }
    }()

    // Send an initial value to start the chain
    c1 <- 1

    // Wait for a short time
    time.Sleep(1000000000 * 1)

    // Send another value to the channel
    c1 <- 2

    // Wait for a long time to observe the issue
    time.Sleep(1000000000 * 50)
}</code>
Nach dem Login kopieren

In diesem Fall bleibt der Ausgang hängen, nachdem der Wert „2“ gesendet wurde:

G1 got 1
G2 got 1
G1 got 1
G2 got 1
G1 got 2
Nach dem Login kopieren

Dieses Problem tritt auf, weil die Goroutinen darauf warten, dass einander Werte von ihren jeweiligen Kanälen empfängt. Daher kann keine der Goroutinen fortfahren und es kommt zu einem Deadlock.

Um Deadlocks zu verhindern, stellen Sie sicher, dass die Kanäle ordnungsgemäß synchronisiert sind. Ein Ansatz besteht darin, gepufferte Kanäle mit einer Kapazität ungleich Null zu verwenden, wie im folgenden Beispiel:

<code class="go">// ... (Same code as before)
c1 := make(chan int, 1) // Buffered channel with capacity of 1
c2 := make(chan int, 1)</code>
Nach dem Login kopieren

Mit gepufferten Kanälen kann eine Goroutine einen Wert senden, auch wenn die andere Goroutine den vorherigen noch nicht empfangen hat eins. Dies hilft, Deadlocks in Situationen wie der beschriebenen zu vermeiden.

Das obige ist der detaillierte Inhalt vonWarum verursachen Go-Kanäle Deadlocks und wie können wir sie verhindern?. 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