追踪了一圈 , 最终追踪到timerproc , 发现了sendTimer被调用位置f(arg, seq) , 而且可以看到将channel c传到了sendTimer中 。
上面的这堆代码逻辑是什么意思呢?
- 所有timer统一使用一个最小堆结构去维护 , 按照timer的when(到期时间)比较大小;
- for循环过程中 , 如果delta = t.when - now的时间大于0 , 则break , 直到有到时间的timer才进行操作;
- timer处理线程从堆顶开始处理每个timer , 对于到期的timer , 如果其period>0 , 则表明该timer 属于Ticker类型 , 调整其下次到期时间并调整其在堆中的位置 , 否则从堆中移除该timer;
- 调用该timer的处理函数以及其他相关工作;
本质上GoLang用channel和堆实现了定时器功能 , 让我们来mock一下 , 伪代码如下:
func cronMock() { for { //从堆中获取时间最近的定时器 t := getNearestTime() //如果时间还没到 , 则continue t.delta > 0 { continue }else{ //时间到了 , 将当前的定时器再加一个钟 t.when += t.duration //将堆重新排序 siftdownTimer() //执行当前定时器指定的函数 , 即sendTimer t.sendTimer() } }}
资料- golang进阶(八)——隐藏技能go:linkname https://blog.csdn.net/lastsweetop/article/details/78830772
- 从99.9%CPU浅谈Golang的定时器实现原理https://www.jianshu.com/p/c9e8aaa13415
【一文搞懂GoLang定时器实现原理】
推荐阅读
- 盘点使用golang作为后台的科技公司
- 彻底搞懂虚拟地址翻译为物理地址的过程
- 一文看懂USB4
- 彻底搞懂虚拟内存,虚拟地址,虚拟地址空间
- 如何彻底搞懂Mysql事务原理
- MySQL高级进阶:关于InnoDB存储结构,一文深入分析讲解
- 帮你彻底搞懂 JS 中的 prototype、__proto__与constructor
- 一文看懂技术中台、研发中台、移动中台建设全攻略
- 一文弄清Python网络爬虫解析库!内含多个实例讲解
- 一文看完CDN的发展历程