TGViewer
Библиотека Go-разработчика | Golang Библиотека Go-разработчика | Golang @goproglib · 24.1K subscribers
Post #7277 2.86K
🤔 Переживёт ли канал Timer.C вызовы Reset

Частый вопрос про таймеры в Go. Вы создаёте time.Timer, сохраняете в отдельной переменной ссылку на канал Timer.C и хотите понять, остаётся ли этот канал тем же самым после вызова Reset. Если канал пересоздаётся, сохранённая ссылка станет бесполезной, а горутина будет ждать данные, которые никогда не придут.

🖇 Короткий ответ

Канал Timer.C не пересоздаётся при вызове Reset. Вы можете хранить его отдельно, читать из него, ждать на нём, и он остаётся живым после любого числа вызовов Reset. Метод Reset меняет только момент срабатывания, сам канал он не трогает.

Проверить это можно небольшой программой. Таймер срабатывает, мы печатаем прошедшее время, удваиваем задержку и снова запускаем тот же таймер:
package main

import (
"fmt"
"time"
)

func main() {
start := time.Now()
delay := time.Second
t := time.NewTimer(delay)
defer t.Stop()

for range t.C {
fmt.Println(time.Since(start))
delay *= 2
t.Reset(delay)
if delay > 16*time.Second {
return
}
}
}


Цикл for range t.C читает из одного и того же канала на каждой итерации. Если бы Reset подменял канал, цикл завис бы после первого срабатывания. Этого не происходит, программа печатает растущие интервалы, пока задержка не превысит шестнадцать секунд.

Отдельно стоит вспомнить про изменение в Go 1.23. Раньше канал таймера имел буфер на один элемент, поэтому после Stop или Reset в нём мог остаться старый сигнал, и его приходилось вручную вычитывать.

❗️ С версии 1.23 канал стал небуферизованным, устаревшие значения больше в нём не задерживаются. Ещё таймеры и тикеры теперь освобождаются сборщиком мусора сразу, как только на них не осталось ссылок, даже без вызова Stop.

Момент про сборку мусора в этом сценарии не важен. Программа держит ссылку и на сам таймер, и на его канал, поэтому ничего не освобождается раньше времени.

Хранить Timer.C в отдельной переменной безопасно. Канал живёт столько же, сколько и сам таймер, а Reset влияет только на время срабатывания. Если вы пишете на Go 1.23 или новее, вручную чистить канал после Reset тоже не нужно, и это убирает старый источник ошибок.

📍 Навигация: Вакансии • Задачи • Собесы • Канал в Max

🐸 Библиотека Go-разработчика

#GoDeep
  • ❤ 3
  • 👍 3
More from @goproglib
  1. Sep 28, 2026🤔 Вопрос с собеседования по Go Что выведет программа? ❤️ — 1 true / 0 false 🔥 — 1 true /…
  2. Sep 28, 2026👩‍💻 Что на самом деле происходит внутри Go map? После Go 1.24 обычный map внутри работае…
  3. Sep 26, 2026🔥 В Go 1.27 появился portable SIMD До этого SIMD-оптимизации в Go требовали архитектурног…
  4. Sep 25, 2026🤡🤡 📍 Навигация: Вакансии • Задачи • Собесы 🐸 Библиотека Go-разработчика #GoGiggle
  5. Sep 25, 2026💡 Код работает. А data race уже есть В Go можно записать значение в одной горутине, прочи…
  6. Sep 23, 2026💥 TCP/IP: что происходит с данными в сети Когда Go-приложение отправляет данные по сети,…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →