永久免费手机建站平台东莞凤岗做网站
永久免费手机建站平台,东莞凤岗做网站,小程序 手机网站,潍坊住房公积金Ticker是周期性定时器.即周期性的触发一个事件.通过Ticker本身提供的管道将事件
传递出去.
Ticker数据结构:
源码位置:src/time/tick.go
type Ticker struct {C -chan Time // The channel on which the ticks are delivered.initTicker bool
}
Ticker对外仅…Ticker是周期性定时器.即周期性的触发一个事件.通过Ticker本身提供的管道将事件传递出去.Ticker数据结构:源码位置:src/time/tick.gotype Ticker struct { C -chan Time // The channel on which the ticks are delivered. initTicker bool }Ticker对外仅暴露了一个channel.当指定时间到来时就往该channel中写入系统时间.即一个事件.1.简单定时任务:func main() { ticker : time.NewTicker(1 * time.Second) defer ticker.Stop() for range ticker.C { log.Println(tick) } }执行结果:定时聚合任务:示例:func TickerLaunch() { //5分钟执行一次. ticker : time.NewTicker(5 * time.Minute) defer ticker.Stop() maxPassenger : 30 passengers : make([]string, 0, maxPassenger) for { passenger : GetNewPassenger() if passenger ! { passengers append(passengers, passenger) } else { time.Sleep(1 * time.Second) } select { case -ticker.C: Launch(passengers) passengers []string{} default: if len(passengers) maxPassenger { Launch(passengers) passengers []string{} } } } } func Launch(passengers []string) { for i : range passengers { fmt.Println(passengers[i], 发车了) } } func GetNewPassenger() string { return 乘客 }2.Ticker对外接口:1)创建定时器:源码位置:src/time/tick.gofunc NewTicker(d Duration) *Ticker { if d 0 { panic(non-positive interval for NewTicker) } // Give the channel a 1-element time buffer. // If the client falls behind while reading, we drop ticks // on the floor until the client catches up. c : make(chan Time, 1) t : (*Ticker)(unsafe.Pointer(newTimer(when(d), int64(d), sendTime, c, syncTimer(c)))) t.C c return t }2).停止定时器:源码位置:src/time/tick.go// Stop turns off a ticker. After Stop, no more ticks will be sent. // Stop does not close the channel, to prevent a concurrent goroutine // reading from the channel from seeing an erroneous tick. func (t *Ticker) Stop() { if !t.initTicker { // This is misuse, and the same for time.Timer would panic, // but this didnt always panic, and we keep it not panicking // to avoid breaking old programs. See issue 21874. return } stopTimer((*Timer)(unsafe.Pointer(t))) }流程图:总流程图:3.简单接口:在有些场景下.启动一个定时器后.该定时器永远不会停止.比如定时轮询任务.此时可以使用一个简单的Tick函数来获取定时器的管道.函数如下:源码位置:src/runtime/tick.gofunc Tick(d Duration) -chan Time { if d 0 { return nil } return NewTicker(d).C }从源码可以看出其实是创建了一个Ticker.然后只返回了管道.并没有返回ticker.所以没有办法停止.4.错误示例:当Ticker用于for循环时.很容易出现意想不到的资源泄漏问题.示例:func WrongTicker() { for { select { case -time.Tick(time.Second): log.Printf(resource leak!) } } }上面的代码.select每次检测case语句都会创建一个定时器.for循环又会不断的执行select语句.系统里会有越来越多的定时器不断地消耗CPU资源.最终CPU资源被耗尽.兜兜转转.何以解忧.如果大家喜欢我的分享的话.可以关注我的微信公众号念何架构之路