概述
在看 Node http 模块文档的时候, 才留意到
server.timeout
这个属性, 本想简单介绍一下, 但是在梳理过后发现关于timeout
有庞大的内容支撑:server.timout -> node core timers -> uv timers -> linux msleep/hrtimer -> clocksource -> tsc -> cmos rtc -> clock cycle
, 所以拆分成几部分大致做下介绍, 期望定时器系列结束之后, noder 能够大致明白:clock cycle
是如何驱动 linux 的msleep/hrtimer
;linux 的 timers 与 uv timers 的关系;node timers 与 uv timers的关系。
在Libuv中的timer中大胆猜测了epoll是通过linux中低精度定时器
实现的,不幸的是只猜对了一半。关于epoll在timer中的应用需要关注两个地方: 同步阻塞
和定时触发
,其中定时触发是通过linux的高精度定时器实现的(其实linux只要支持高精度定时器,最终所有的定时器都是高精度定时器,只不过低精度定时器是通过高精度定时器模拟出来的)。
定时器
在整个学习定时器阅读源码的过程中,个人一直非常关注的地方就是触发源
,什么触发了代码的执行。触发源的本质有两种: 硬件触发
,软件触发
。
软件触发
while(true) {
const now = getTimeFromTimeKeeper();
if (now === '双11') {
emitEventInvokeActions();// 触发源
}
schedule()
}
硬件触发
硬件触发通过发送中断信号
,告知CPU执行指定的中断程序,在中断程序中判断是否到达指定时间,比软件触发的代价更低。关于硬件启动注册及切换
的过程,可以通过/var/log/dmesg
查看
#$ cat dmesg|grep -i -E "hz|clock|time|tsc|rtc|apic|hpet"
...
[ 1.792655] kernel: clocksource: Switched to clocksource tsc
...
epoll 定时触发
现代计算机中无论高精度还是低精度都是通过硬件中断的方式来实现定时的,所以关于epoll 定时触发没有什么神秘可言。
通过linux源码中epoll-wait
的系统调用SYSCALL_DEFINE4(epoll_wait,..., int timeout)
死盯timeout
参数一步步追踪可以发现:
static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
int maxevents, long timeout)
{
...
struct timespec64 end_time = ep_set_mstimeout(timeout);
*to = timespec64_to_ktime(end_time); // 转成 纳秒精度
schedule_hrtimeout_range(to, slack, HRTIMER_MODE_ABS); // 后面触发工作就是定时器的任务了
...
__set_current_state(TASK_INTERRUPTIBLE);// 可中断的睡眠状态
...
__set_current_state(TASK_RUNNING);// 可运行状态。未必正在使用CPU,也许是在等待调度
...
}
定时器的基本原理比较简单,但是由上可知,定时器是异步触发的,那epoll是如何做到同步阻塞的呢?
epoll 同步阻塞
Libuv中定时器严重依赖于epoll的同步阻塞
功能,触发问题通过高精度定时器来解决了,那同步问题如何解决?--进程调度
(复习下操作系统基本原理)
由上面代码可知在ep_poll方法中,主动调用__set_current_state
方法,使进程进入TASK_INTERRUPTIBLE
状态,退出CPU调度,进入等待执行状态
,该状态可以被中断唤醒
,而等待的中断就是我们设置的定时器产生的(通过设置APIC硬件的cycles)。
epoll 姗姗来迟
epoll 这么香,为什么在2.6内核版本的时候才开始引入?
作为大前端开发人员,咱对linux发展史不熟悉,但是咱对react熟悉呀。回顾下react发展史,component + stackReconcile -> fiberReconcile + hook -> concurrencyReconcile + hook。concurrencyReconcile +hook这么香,尤其是hook,那为什么一开始没有引入到react中?
软件是是演化而来的,而不是设计出来的。每个时代的产物都与当时的时代背景紧密相关,而不能在一个新的时代去思考旧时代的为什么。时代在发展,人也在进步,活在当下。
最后
以上就是正直老师为你收集整理的epoll原理_定时器: Linux 中的 epoll的全部内容,希望文章能够帮你解决epoll原理_定时器: Linux 中的 epoll所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复