Das Paket time bietet zwei nützliche Werkzeuge: Timer und Ticker.
Wesentliche Unterschiede:
Timer "geht aus", nachdem er ausgelöst wurde; er muss zurückgesetzt werden (Reset), um ihn erneut zu verwenden.Ticker erzeugt Ereignisse, solange er nicht ausdrücklich mit der Methode Stop() gestoppt wird.Besonderheiten der Verwendung:
Stop() bei Timer/Ticker beim Beenden auf, um Ressourcenlecks zu vermeiden.Stop() bei Timer ist möglicherweise erforderlich, den Kanal "zu leeren": Wenn der Timer vor Stop() ausgelöst wurde, muss aus dem Kanal gelesen werden.Beispiel für die korrekte Verwendung von Timer:
t := time.NewTimer(2 * time.Second) defer t.Stop() // unbedingt! select { case <-t.C: fmt.Println("Die Zeit ist um!") case <-otherDone: if !t.Stop() { <-t.C // Kanal leeren, falls nötig } }
Kann man Timer sofort wiederverwenden, nachdem man einen Wert aus dem Kanal t.C erhalten hat? Was passiert, wenn man t.Stop() nicht aufruft?
Antwort: Der Timer sollte nicht sofort zurückgesetzt werden, ohne Stop() aufzurufen und möglicherweise aus dem Kanal zu lesen. Wenn t.Stop() nicht aufgerufen wird, könnte eine "tote" Goroutine zurückbleiben oder ein unerwarteter Trigger im nächsten Zyklus auftreten (der Kanal ist nicht geleert). Die richtige Verwendung: Rufen Sie Stop() auf, und wenn Stop() false zurückgibt, leeren Sie unbedingt den Kanal durch Lesen von t.C.
Geschichte
Geschichte
Ticker verwendet, der beim Beenden des Handlers nicht gestoppt wurde. Der Handler "hing" selbst nach der Löschung des Benutzers und verbrauchte weiterhin CPU.Geschichte
In Tests wurde Stop() für den Timer nicht aufgerufen — die Tests hingen zufällig, weil der Timerkanal nicht freigegeben wurde, der zweite "Ping" vom Timer, der nie kam, wurde erwartet.