Heim > Artikel > Backend-Entwicklung > Wie lege ich ein Timeout für WaitGroup.Wait() in Go fest?
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!