Heim  >  Artikel  >  Backend-Entwicklung  >  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
Mary-Kate OlsenOriginal
2024-11-02 09:50:03394Durchsuche

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>

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>

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

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>

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!

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