第
GoLang中的timer定时器实现原理分析
//NewTimercreatesanewTimerthatwillsend
//thecurrenttimeonitschannelafteratleastdurationd.
funcNewTimer(dDuration)*Timer{
c:=make(chanTime,1)
t:=Timer{
C:c,
r:runtimeTimer{
when:when(d),
f:sendTime,
arg:c,
startTimer(t.r)
returnt
//TheTimertyperepresentsasingleevent.
//WhentheTimerexpires,thecurrenttimewillbesentonC,
//unlesstheTimerwascreatedbyAfterFunc.
//ATimermustbecreatedwithNewTimerorAfterFunc.
typeTimerstruct{
C-chanTime
rruntimeTimer
funcNewTicker(dDuration)*Ticker{
ifd=0{
panic(errors.New(non-positiveintervalforNewTicker))
//Givethechannela1-elementtimebuffer.
//Iftheclientfallsbehindwhilereading,wedropticks
//ontheflooruntiltheclientcatchesup.
c:=make(chanTime,1)
t:=Ticker{
C:c,
r:runtimeTimer{
when:when(d),
period:int64(d),
f:sendTime,
arg:c,
startTimer(t.r)
returnt
typeTickerstruct{
C-chanTime//Thechannelonwhichtheticksaredelivered.
rruntimeTimer
ticker跟timer的初始化过程差不多,但是ticker比timer多了一个period参数,意为间隔的意思。
//Interfacetotimersimplementedinpackageruntime.
//Mustbeinsyncwith../runtime/time.go:/^typetimer
typeruntimeTimerstruct{
ppuintptr
whenint64//触发时间
periodint64//执行周期性任务的时间间隔
ffunc(any,uintptr)//执行的回调函数,NOTE:mustnotbeclosure
argany//执行任务的参数
sequintptr//回调函数的参数,该参数仅在netpoll的应用场景下使用
nextwhenint64//如果是周期性任务,下次执行任务时间
statusuint32//状态
//sendTimedoesanon-blockingsendofthecurrenttimeonc.
funcsendTime(cany,sequintptr){
select{
casec.(chanTime)-Now():
default:
sendTime采用非阻塞的形式,意为,不管是否存在接收方,此定时器一旦到时间了就要触发掉。
//runtime/runtime2.go
typepstruct{
.....
//Thewhenfieldofthefirstentryonthetimerheap.
//Thisisupdatedusingatomicfunctions.
//Thisis0ifthetimerheapisempty.
//