Heim > Backend-Entwicklung > Golang > Wie vermeidet man Deadlocks in Go-Goroutinen, wenn die Produzenten nur von kurzer Dauer sind?

Wie vermeidet man Deadlocks in Go-Goroutinen, wenn die Produzenten nur von kurzer Dauer sind?

Linda Hamilton
Freigeben: 2024-10-25 07:09:02
Original
857 Leute haben es durchsucht

How to Avoid Deadlock in Go Goroutines When Producers Are Short-Lived?

Deadlock in Go-Goroutinen auflösen

Bei der gleichzeitigen Programmierung tritt ein Deadlock auf, wenn mehrere Goroutinen auf unbestimmte Zeit darauf warten, dass einander Vorgänge abschließt, wodurch die Operation effektiv angehalten wird Programm. Dieser Artikel befasst sich mit einem bestimmten Deadlock, der bei der Go-Parallelität auftritt, wie in der ursprünglichen Frage beschrieben:

<code class="go">package main

import (
    "fmt"
    "time"
)

func producer(ch chan int, d time.Duration, num int) {
    for i := 0; i < num; i++ {
        ch <- i
        time.Sleep(d)
    }
}

func main() {
    ch := make(chan int)
    go producer(ch, 100*time.Millisecond, 2)
    go producer(ch, 200*time.Millisecond, 5)
    for {
        fmt.Println(<-ch)
    }
    close(ch)
}</code>
Nach dem Login kopieren

Dieser Code löst aufgrund der folgenden Faktoren einen Deadlock-Fehler aus:

  • Die Produzenten , die Werte an den Kanal senden, sind nur von kurzer Dauer und produzieren schließlich keine Daten mehr.
  • Die endlose for-Schleife in der Hauptfunktion empfängt kontinuierlich Werte vom Kanal ohne Beendigungsbedingung.
  • Die Der Kanal wird nach der Endlosschleife geschlossen, sodass keine weiteren Werte mehr zum Empfang verfügbar sind.

Lösung: Koordinierte Beendigung

Um einen Deadlock zu vermeiden, müssen die Produzenten koordiniert werden, um den Abschluss zu signalisieren, und der Kanal muss vom letzten Produzenten geschlossen werden. Hier ist eine effiziente Lösung, die eine sync.WaitGroup zur Koordination verwendet:

<code class="go">func producer(ch chan int, d time.Duration, num int, wg *sync.WaitGroup) {
    defer wg.Done()
    for i := 0; i < num; i++ {
        ch <- i
        time.Sleep(d)
    }
}

func main() {
    wg := &sync.WaitGroup{}
    ch := make(chan int)

    wg.Add(1)
    go producer(ch, 100*time.Millisecond, 2, wg)
    wg.Add(1)
    go producer(ch, 200*time.Millisecond, 5, wg)

    go func() {
        wg.Wait()
        close(ch)
    }()

    for v := range ch {
        fmt.Println(v)
    }
}</code>
Nach dem Login kopieren

In dieser Lösung:

  • Wir erhöhen die WaitGroup für jeden Produzenten.
  • Jeden Produzenten dekrementiert die WaitGroup nach Abschluss durch eine Defer-Anweisung.
  • Eine Goroutine wartet darauf, dass die WaitGroup Null erreicht (was bedeutet, dass alle Produzenten fertig sind) und schließt den Kanal.
  • Die Hauptschleife verwendet einen for-Bereich Konstrukt, um die auf dem Kanal gesendeten Werte zu durchlaufen, bevor er geschlossen wird.

Das obige ist der detaillierte Inhalt vonWie vermeidet man Deadlocks in Go-Goroutinen, wenn die Produzenten nur von kurzer Dauer sind?. 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