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
}
}
Nach dem Login kopieren
- 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
}
}
Nach dem Login kopieren
- 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!