Heim  >  Artikel  >  Backend-Entwicklung  >  Wie lege ich ein Timeout für WaitGroup.Wait() in Go fest?

Wie lege ich ein Timeout für WaitGroup.Wait() in Go fest?

DDD
DDDOriginal
2024-11-12 20:47:02662Durchsuche

How to Set a Timeout for WaitGroup.Wait() in Go?

Timeout für WaitGroup.Wait()

WaitGroup.Wait() kann auf unbestimmte Zeit blockieren und darauf warten, dass alle Goroutinen abgeschlossen sind. Dies kann problematisch sein, wenn Sie Ihr System vor fehlerhaften Arbeitern schützen möchten, die möglicherweise die Ausführung auf unbestimmte Zeit blockieren. Obwohl es keine idiomatische Möglichkeit gibt, ein Timeout für WaitGroup.Wait() festzulegen, gibt es mehrere Ansätze, um diese Funktionalität zu erreichen.

Ein gängiger Ansatz beinhaltet die Verwendung eines Kanals und einer Goroutine. Wenn die Goroutine ihre Arbeit beendet, sendet sie ein Signal an den Kanal. Das Hauptprogramm kann den Kanal und einen Timer auswählen, um festzustellen, ob die Goroutine abgelaufen ist. Hier ist ein Beispiel:

import (
    "sync"
    "time"
)

func main() {
    var wg sync.WaitGroup
    wg.Add(1)

    timeout := time.After(5 * time.Second)
    ch := make(chan struct{})

    go func() {
        defer wg.Done()
        defer close(ch)
        // Do some work
    }()

    select {
    case <-ch:
        // Goroutine finished before timeout
        wg.Wait() // Wait for all goroutines to finish
    case <-timeout:
        // Goroutine timed out
        wg.Wait() // Block until all goroutines have completed
        log.Println("Timeout occurred")
    }
}

Diese Lösung verwendet eine Select-Anweisung, um entweder auf dem Kanal oder einem Timer zu warten und einen Timeout-Mechanismus für WaitGroup.Wait() bereitzustellen. Weitere empfohlene Optimierungen umfassen die Verwendung von Defer-Anweisungen zum Schließen von Kanälen und die Verwendung untypisierter Konstanten für Timeout-Dauer.

Alternativ können Sie eine benutzerdefinierte Hilfsfunktion verwenden, die die oben genannte Funktionalität umschließt, den Code vereinfacht und ihn wiederverwendbar macht. Hier ist ein Beispiel:

func waitTimeout(wg *sync.WaitGroup, timeout time.Duration) bool {
    c := make(chan struct{})
    defer close(c)

    go func() {
        wg.Wait()
        c <- struct{}{}
    }()

    select {
    case <-c:
        return false // Completed normally
    case <-time.After(timeout):
        return true // Timed out
    }
}

Diese Funktion kann wie folgt verwendet werden:

if waitTimeout(&wg, 5*time.Second) {
    fmt.Println("Timed out waiting for wait group")
} else {
    fmt.Println("Wait group finished")
}

Diese Ansätze bieten eine Möglichkeit, eine Zeitüberschreitung für WaitGroup.Wait() festzulegen, sodass Sie sich schützen können Ihr System vor fehlerhaften Arbeitern, die die Ausführung auf unbestimmte Zeit blockieren.

Das obige ist der detaillierte Inhalt vonWie lege ich ein Timeout für WaitGroup.Wait() in Go fest?. 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