Timeouts mit Kanälen in Go verwenden
Goroutinen und Kanäle bieten einen leistungsstarken Mechanismus für die gleichzeitige Programmierung in Go. Der Umgang mit Zeitüberschreitungen in Goroutinen kann jedoch schwierig sein.
In einem Szenario, in dem Sie die Erreichbarkeit einer Liste von URLs mithilfe von Goroutinen und einer Zeitüberschreitung überprüfen möchten, kann es Situationen geben, in denen die Zeitüberschreitung nicht ausgeführt wird, selbst wenn Einige der URLs sind nicht erreichbar.
Lassen Sie uns den bereitgestellten Code analysieren:
func check(u string) bool { time.Sleep(4 * time.Second) return true } func IsReachable(urls []string) bool { ch := make(chan bool, 1) for _, url := range urls { go func(u string) { select { case ch <- check(u): case <-time.After(time.Second): ch <- false } }(url) } return <-ch }
Das Problem liegt in der Funktion prüfen. Wenn Sie time.Sleep in einer Goroutine verwenden, wird die aktuelle Goroutine angehalten, in diesem Fall die Goroutine, die die Prüffunktion ausführt. Während die Prüffunktion angehalten ist, versucht die Select-Anweisung in der äußeren Goroutine weiterhin auszuführen.
In diesem Fall sind beide Zweige der Select-Anweisung (Überprüfung des Ergebnisses oder der Zeitüberschreitung) nach 4 ausführbar Sekunden, wenn der Scheck zurückgegeben wird. Da jedoch beide Zweige ausführbar sind, kann die Laufzeit einen von beiden ausführen, was dazu führen kann, dass immer „true“ zurückgegeben wird.
Um dieses Problem zu lösen, müssen Sie für jede Prüffunktion eine neue Goroutine erstellen, wie in gezeigt der korrigierte Code unten:
func check(u string, checked chan<- bool) { time.Sleep(4 * time.Second) checked <- true } func IsReachable(urls []string) bool { ch := make(chan bool, 1) for _, url := range urls { go func(u string) { checked := make(chan bool) go check(u, checked) select { case ret := <-checked: ch <- ret case <-time.After(time.Second): ch <- false } }(url) } return <-ch }
In diesem Fall wird die Prüffunktion in einer separaten Goroutine ausgeführt, um sicherzustellen, dass sie die äußere Goroutine nicht anhält und das Timeout korrekt sein kann ausgeführt.
Das obige ist der detaillierte Inhalt vonWie implementiert man Timeouts in Go-Goroutinen mit Kanälen richtig?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!