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

Wie implementiert man ein Timeout für WaitGroup.Wait() in Go?

Susan Sarandon
Susan SarandonOriginal
2024-11-12 17:17:01877Durchsuche

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

Timeout für WaitGroup.Wait(): Idiomatische Ansätze

In Go kann ein Zeitlimit für WaitGroup.Wait() festgelegt werden, um endloses Warten auf fehlerhafte Mitarbeiter zu verhindern . Hier finden Sie eine detaillierte Untersuchung idiomatischer Möglichkeiten zur Implementierung und alternativer Ansätze.

Empfohlene Lösung: Verwendung eines Timers und Kanals

Der folgende Ansatz wird allgemein als die idiomatischste Lösung angesehen:

import (
    "sync"
    "time"
)

func waitTimeout(wg *sync.WaitGroup, timeout time.Duration) bool {
    c := make(chan struct{})
    go func() {
        wg.Wait()
        close(c)
    }()
    select {
    case <-c:
        return false // completed normally
    case <-time.After(timeout):
        return true // timed out
    }
}
  • Ein Kanal (c) wird erstellt, um zu signalisieren, wenn die Wartegruppe ihre Wartezeit beendet.
  • Eine Goroutine wird erzeugt, um wg.Wait() aufzurufen und den Kanal zu schließen, wenn sie fertig ist.
  • Eine Select-Anweisung wartet darauf, dass entweder der Kanal geschlossen wird oder eine Zeitüberschreitung auftritt.
  • Wenn der Kanal geschlossen ist, gibt die Funktion „false“ zurück, was auf einen normalen Abschluss hinweist.
  • Wenn die Wenn die Zeitüberschreitung erreicht ist, gibt die Funktion „true“ zurück, was eine Zeitüberschreitung bedeutet.

Vereinfachung der empfohlenen Lösung

Bedenken Sie für eine einfachere Implementierung Folgendes:

  • Schließen Sie den Kanal, um den Abschluss zu signalisieren, anstatt einen Wert zu senden.
  • Verwenden Sie „Defer“, um den Kanal zu schließen, auch wenn die Funktion vorzeitig beendet wird.
  • Entfernen Sie die Wartegruppe, wenn nur auf einen Job gewartet werden muss .
  • Verwenden Sie Zeitdauern direkt ohne Konvertierungen (z. B. time.Second).

Alternativer Ansatz: Verwendung eines stornierbaren Kontexts

Ein alternativer Ansatz beinhaltet die Verwendung eines stornierbaren Kontexts Kontext:

import (
    "context"
    "sync/atomic"
    "sync"
)

func waitWithCancel(ctx context.Context, wg *sync.WaitGroup) bool {
    ctxDone := make(chan struct{})
    var exited int32
    go func() {
        defer close(ctxDone)
        wg.Wait()
        atomic.StoreInt32(&exited, 1)
    }()

    select {
    case <-ctx.Done():
        return atomic.LoadInt32(&exited) == 0
    case <-ctxDone:
        return true
    }
}
  • Ein abbrechbarer Kontext (ctx) wird erstellt.
  • Ein Kanal (ctxDone) wird verwendet, um zu signalisieren, wenn der Kontext abgebrochen wird.
  • Eine Goroutine wird erzeugt, um auf die Wartegruppe zu warten und dem ctxDone-Kanal ein Signal zu geben.
  • Eine Select-Anweisung wartet darauf, dass entweder der Kontext abgebrochen oder die Wartegruppe abgeschlossen wird.
  • Wenn der Kontext vorhanden ist Wenn der Vorgang abgebrochen wird, kehrt die Funktion basierend darauf zurück, ob die Wartegruppe ihre Wartezeit bereits beendet hat.

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