Пакет time предоставляет два полезных инструмента: Timer и Ticker.
Ключевые отличия:
Timer после срабатывания "потухает", его нужно сбросить (Reset), чтобы использовать ещё раз.Ticker генерирует события до тех пор, пока явно не остановлен методом Stop().Особенности использования:
Stop() у Timer/Ticker при завершении работы, чтобы не возникало утечек ресурсов.Stop() у Timer, возможно требуется «осушить» канал: если таймер сработал до Stop(), чтение из канала обязательно.Пример корректного использования Timer:
t := time.NewTimer(2 * time.Second) defer t.Stop() // обязательно! select { case <-t.C: fmt.Println("Time's up!") case <-otherDone: if !t.Stop() { <-t.C // осушаем канал, если нужно } }
Можно ли сразу повторно использовать Timer после получения значения из канала t.C? Что произойдет, если не сделать t.Stop()?
Ответ: Таймер не должен немедленно сбрасываться без вызова Stop() и возможного чтения из канала. Если не сделать t.Stop(), может остаться "мертвая" горутина или неожиданный триггер на следующем цикле (канал не очищен). Правильное использование: вызовите Stop(), а если Stop() вернул false — обязательно осушите канал чтением из t.C.
История
История
Ticker, который не останавливали при завершении хендлера. Обработчик "висел" даже после удаления пользователя, продолжается тратить CPU.История
В тестах не вызывали Stop() для таймера — тесты висли рандомно из-за того, что канал таймера не освобождался, ожидался второй "пинг" от таймера, который никогда не приходил.