Go中用ticker+channel实现并发定时器的核心是:ticker产生周期时间信号,channel控制启停与参数传递,goroutine实现非阻塞可取消任务;需调用Stop防泄漏,用done或context优雅终止,多任务应独立ticker和channel。
使用 Go 的 ticker 和 channel 组合实现并发定时器,核心在于:用 time.Ticker 产生周期性时间信号,用 channel 控制启停、传递任务参数或接收结果,再配合 goroutine 实现非阻塞、可取消、可扩展的周期性任务管理。
time.Ticker 会按固定间隔向其 C 字段(一个 chan time.Time)发送当前时间。启动一个 goroutine 监听该 channel,即可执行周期逻辑:
ticker := time.NewTicker(5 * time.Second) defer ticker.Stop()go func() { for range ticker.C { fmt.Println("执行周期任务:", time.Now()) // 这里放你的业务逻辑,如采集指标、清理缓存等 } }()
注意:必须调用 ticker.Stop() 防止 goroutine 泄漏;for range ticker.C 是标准写法,自动处理 channel 关闭。
直接关闭 ticker.C 不安全,应通过额外的 done channel 控制循环退出:
done := make(chan struct{}) 作为停止信号ticker.C 和 done,任一触发即响应示例:
func runPeriodicTask(interval time.Duration, done chan struct{}) {
ticker := time.NewTicker(interval)
defer ticker.Stop()
for {
select {
case <-ticker.C:
fmt.Println("任务运行中...")
// 执行具体工作(建议加 recover 防 panic 中断)
case <-done:
fmt.Println("任务已停止")
return
}
}}
// 使用
done := make(chan struct{})
go runPeriodicTask(3*time.Second, done)
// 停止时
close(done)
并发多任务 + 参数隔离:为每个任务分配独立 channel
若需同时运行多个不同周期、不同参数的任务(例如:每 10s 检查磁盘,每 30s 上报日志),不要共用一个 ticker。应为每个任务创建独立 ticker 和控制 channel:
done channel,便于统一停止简单多任务管理示意:
type Task struct {
Name string
Interval time.Duration
Action func()
Done chan struct{}
}
func (t *Task) Start() {
ticker := time.NewTicker(t.Interval)
go func() {
defer ticker.Stop()
for {
select {
case <-ticker.C:
t.Action()
case <-t.Done:
return
}
}
}()
}
// 启动多个
tasks := []Task{
{Name: "disk-check", Interval: 10 time.Second, Action: checkDisk},
{Name: "log-report", Interval: 30 time.Second, Action: reportLogs},
}
for i := range tasks {
tasks[i].Done = make(chan struct{})
tasks[i].Start()
}
// 停止全部
for _, t := range tasks {
close(t.Done)
}
当周期任务内部含 I/O 操作(如数据库查询、HTTP 调用),推荐用 context.Context 替代裸 done channel,获得超时、截止时间、父子取消链等能力:
context.WithTimeout 或 context.WithCancel 包装任务上下文ctx.Done(),而非自定义 done channelhttp.Client.Do)应接受该 ctx示例片段:
func runWithCtx(ctx context.Context, interval time.Duration, work func(context.Context)) {
ticker := time.NewTicker(interval)
defer ticker.Stop()
for {
select {
case <-ticker.C:
// 每次执行都传入新衍生的子 context(可设单次超时)
childCtx, cancel := context.WithTimeout(ctx, 2*time.Second)
work(childCtx)
cancel()
case <-ctx.Done():
return
}
}}
不复杂但容易忽略:Ticker 的精度受系统调度和 GC 影响,不适合毫秒级强实时场景;高频任务建议用 time.AfterFunc 链式重启,或引入更专业的调度库(如 asynq、gocron)处理复杂依赖与持久化需求。
# go
# golang
# for
# 封装
# select
# 循环
# Struct
# map
# 并发
# channel
# 数据库
# http
# 多个
# 链式
# 进阶
# 周期函数
# 只需
# 可取消
# 自定义
# 不适合
# 而非
# 重启
相关文章:
广州美橙建站如何快速搭建多端合一网站?
如何用PHP工具快速搭建高效网站?
如何高效搭建专业期货交易平台网站?
实现虚拟支付需哪些建站技术支撑?
制作网站的软件下载免费,今日头条开宝箱老是需要下载怎么回事?
建站之星2.7模板:企业网站建设与h5定制设计专题
桂林网站制作公司有哪些,桂林马拉松怎么报名?
建站之星如何优化SEO以实现高效排名?
南京网站制作费用,南京远驱官方网站?
如何选择可靠的免备案建站服务器?
建站之星如何快速解决建站难题?
如何选择长沙网站建站模板?H5响应式与品牌定制哪个更优?
网站制作模板下载什么软件,ppt模板免费下载网站?
美食网站链接制作教程视频,哪个教做美食的网站比较专业点?
如何零成本快速生成个人自助网站?
盘锦网站制作公司,盘锦大洼有多少5G网站?
制作网站公司那家好,网络公司是做什么的?
佛山企业网站制作公司有哪些,沟通100网上服务官网?
如何在香港免费服务器上快速搭建网站?
Python lxml的etree和ElementTree有什么区别
沈阳个人网站制作公司,哪个网站能考到沈阳事业编招聘的信息?
如何在橙子建站上传落地页?操作指南详解
建站为何优先选择香港服务器?
如何在云主机快速搭建网站站点?
长春网站建设制作公司,长春的网络公司怎么样主要是能做网站的?
浙江网站制作公司有哪些,浙江栢塑信息技术有限公司定制网站做的怎么样?
行程制作网站有哪些,第三方机票电子行程单怎么开?
建站之星后台密码如何安全设置与找回?
如何高效生成建站之星成品网站源码?
子杰智能建站系统|零代码开发与AI生成SEO优化指南
高防服务器租用指南:配置选择与快速部署攻略
手机怎么制作网站教程步骤,手机怎么做自己的网页链接?
焦点电影公司作品,电影焦点结局是什么?
专业的网站制作设计是什么,如何制作一个企业网站,建设网站的基本步骤有哪些?
安云自助建站系统如何快速提升SEO排名?
高配服务器限时抢购:企业级配置与回收服务一站式优惠方案
如何高效完成自助建站业务培训?
天津个人网站制作公司,天津网约车驾驶员从业资格证官网?
建站与域名管理如何高效结合?
极客网站有哪些,DoNews、36氪、爱范儿、虎嗅、雷锋网、极客公园这些互联网媒体网站有什么差异?
商务网站制作工程师,从哪几个方面把握电子商务网站主页和页面的特色设计?
建站主机服务器选型指南与性能优化方案解析
h5在线制作网站电脑版下载,h5网页制作软件?
安徽网站建设与外贸建站服务专业定制方案
C++时间戳转换成日期时间的步骤和示例代码
外贸公司网站制作哪家好,maersk船公司官网?
php条件判断怎么写_ifelse和switchcase的使用区别【对比】
,有什么在线背英语单词效率比较高的网站?
TestNG的testng.xml配置文件怎么写
武汉外贸网站制作公司,现在武汉外贸前景怎么样啊?
*请认真填写需求信息,我们会在24小时内与您取得联系。