Heim >Backend-Entwicklung >Golang >Wie kann sichergestellt werden, dass die Go-Routinen vor den Hauptausgängen abgeschlossen sind?

Wie kann sichergestellt werden, dass die Go-Routinen vor den Hauptausgängen abgeschlossen sind?

DDD
DDDOriginal
2024-12-09 16:33:14779Durchsuche

How to Ensure Go Routines Complete Before Main Exits?

Warten auf den Abschluss der Go-Routine

In Go ist es üblich, Goroutinen zu verwenden, um gleichzeitige Aufgaben auszuführen. Um sicherzustellen, dass das Hauptprogramm auf den Abschluss aller Goroutinen wartet, bevor es beendet wird, ist es wichtig, geeignete Synchronisierungsmechanismen zu implementieren.

Ein Ansatz, wie in der Frage erwähnt, beinhaltet die Verwendung eines booleschen Kanals (fertig):

func do_stuff(done chan bool) {
    fmt.Println("Doing stuff")
    done <- true
}
func main() {
    fmt.Println("Main")
    done := make(chan bool)
    go do_stuff(done)
    <-done
}

Warum <-done Funktioniert:

Die Operation <-done ist ein blockierender Kanalempfang. Es wird gewartet, bis ein Wert auf dem Kanal „Fertig“ gesendet wird. Im bereitgestellten Code sendet do_stuff nach Abschluss der Aufgabe „true“ auf dem Kanal, was dazu führt, dass der <-done-Vorgang in „main“ erfolgreich ist.

Deadlock durch Auskommentieren der letzten Zeile:

Das Auskommentieren der letzten Zeile in main führt zu einem Deadlock:

func main() {
    fmt.Println("Main")
    done := make(chan bool)
    go do_stuff(done)
    <-done
    // <-done
}

Dieser zweite <-fertige Vorgang versucht, aus einem leeren Kanal zu lesen, ohne dass eine Goroutine Werte an ihn sendet. Infolgedessen hängt das Programm in einem Deadlock.

Alternative Synchronisierungsmethode mit dem Sync-Paket:

Für komplexere Szenarien bietet das Sync-Paket alternative Synchronisierungsprimitive. Im bereitgestellten Code kann sync.WaitGroup den Abschluss von Goroutinen effektiv verfolgen:

package main

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

func main() {
    var wg sync.WaitGroup
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func() {
            longOp()
            wg.Done()
        }()
    }
    // will wait until wg.Done is called 10 times (10 goroutines finish)
    wg.Wait()
}

func longOp() {
    time.Sleep(time.Second * 2)
    fmt.Println("long op done")
}

Die Verwendung von sync.WaitGroup stellt sicher, dass main auf den Abschluss aller 10 Goroutinen wartet, bevor das Programm beendet wird.

Das obige ist der detaillierte Inhalt vonWie kann sichergestellt werden, dass die Go-Routinen vor den Hauptausgängen abgeschlossen sind?. 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