/// runtime/proc.go func schedule() { ... pp := _g_.m.p.ptr() // 获取当前P ... checkTimers(pp, 0) } func checkTimers(pp *p, now int64) (rnow, pollUntil int64, ran bool) { ... lock(&pp.timersLock) adjusttimers(pp) rnow = now if len(pp.timers) > 0 { if rnow == 0 { rnow = nanotime() } for len(pp.timers) > 0 { // timers集合大于0,循环 if tw := runtimer(pp, rnow); tw != 0 { if tw > 0 { pollUntil = tw } break // checkTimers结束 } ran = true } } ... unlock(&pp.timersLock) return rnow, pollUntil, ran } func runtimer(pp *p, now int64) int64 { for { t := pp.timers[0] // 最小堆的第一个 switch s := atomic.Load(&t.status); s { case timerWaiting: if t.when > now { // 时间还没到,返回到期时间,checkTimers的for循环也会终止 return t.when } if !atomic.Cas(&t.status, s, timerRunning) { continue } runOneTimer(pp, t, now) // 时间到期 return 0 ..... } } } func runOneTimer(pp *p, t *timer, now int64) { f := t.f // timer的回调方法,创建时候设置的sendTime arg := t.arg // 创建时候设置的通道 seq := t.seq if t.period > 0 { // t.period > 0说明是ticker delta := t.when - now t.when += t.period * (1 + -delta/t.period) // 设置下一轮的到达时间 siftdownTimer(pp.timers, 0) // 调整最小堆 if !atomic.Cas(&t.status, timerRunning, timerWaiting) { badTimer() } updateTimer0When(pp) // 更新P的到达时间 } else { // 如果不是ticker 则移除出最小堆 dodeltimer0(pp) if !atomic.Cas(&t.status, timerRunning, timerNoStatus) { badTimer() } } unlock(&pp.timersLock) f(arg, seq) // 执行sendTime lock(&pp.timersLock) }