Heim >Backend-Entwicklung >Golang >Wie löst man Deadlocks in Go, wenn alle Goroutinen schlafen?

Wie löst man Deadlocks in Go, wenn alle Goroutinen schlafen?

Susan Sarandon
Susan SarandonOriginal
2024-12-24 10:43:171037Durchsuche

How to Resolve Deadlocks in Go When All Goroutines Are Asleep?

Deadlock in Go: „Alle Goroutinen schlafen“

Bei der Arbeit mit Goroutinen ist es wichtig, den Kanalbetrieb effektiv zu verwalten, um Deadlocks zu vermeiden. Dies geschieht, wenn alle Goroutinen auf unbestimmte Zeit blockiert sind, was zu einer Deadlock-Situation führt.

Den Code verstehen

Sehen wir uns den bereitgestellten Code an:

package main

import (
    "fmt"
    "sync"
    "time"
)

type Item struct {
    name string
}

type Truck struct {
    Cargo []Item
    name  string
}

func UnloadTrucks(c chan Truck) {
    for t := range c {
        fmt.Printf("%s has %d items in cargo: %s\n", t.name, len(t.Cargo), t.Cargo[0].name)
    }
}

func main() {
    trucks := make([]Truck, 2)
    ch := make(chan Truck)

    for i, _ := range trucks {
        trucks[i].name = fmt.Sprintf("Truck %d", i+1)
        fmt.Printf("Building %s\n", trucks[i].name)
    }

    for t := range trucks {
        go func(tr Truck) {
            itm := Item{}
            itm.name = "Groceries"

            fmt.Printf("Loading %s\n", tr.name)
            tr.Cargo = append(tr.Cargo, itm)
            ch <- tr
        }(trucks[t])
    }

    time.Sleep(50 * time.Millisecond)
    fmt.Println("Unloading Trucks")
    UnloadTrucks(ch)

    fmt.Println("Done")
}

Dieser Code erstellt einen Kanal-CH vom Typ Truck und startet zwei Goroutinen, um das Beladen von LKWs mit Lebensmitteln und deren Versand an den Kanal zu simulieren. Anschließend ruft es UnloadTrucks auf, um den Inhalt der LKWs abzurufen und auszudrucken.

Ursache des Deadlocks

Das Problem liegt im Fehlen eines Mechanismus zum Schließen des CH-Kanals. Wenn alle Goroutinen ihre LKWs an den Kanal gesendet haben, gibt es in UnloadTrucks kein Signal zum Beenden der Schleife. Das bedeutet, dass ch weiterhin auf Werte wartet, die nie eintreffen, was zu einem Deadlock führt.

Lösung

Um den Deadlock aufzulösen, müssen wir den Kanal ch explizit schließen, wenn Die Lade-Goroutinen sind abgeschlossen. Wir können eine sync.WaitGroup verwenden, um die laufenden Goroutinen zu zählen und den Kanal zu schließen, wenn alle fertig sind:

var wg sync.WaitGroup

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

Diese Änderung stellt sicher, dass UnloadTrucks beendet wird, sobald alle Goroutinen mit dem Beladen der LKWs fertig sind. Die Wait-Funktion blockiert, bis der WaitGroup-Zähler Null erreicht, was anzeigt, dass alle Goroutinen ihre Arbeit abgeschlossen haben. Das Schließen des Kanals signalisiert UnloadTrucks, dass keine weiteren LKWs mehr empfangen werden können, sodass die Schleife ordnungsgemäß verlassen werden kann.

Das obige ist der detaillierte Inhalt vonWie löst man Deadlocks in Go, wenn alle Goroutinen schlafen?. 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