我是靠谱客的博主 正直老师,最近开发中收集的这篇文章主要介绍epoll原理_定时器: Linux 中的 epoll,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

在看 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的同步阻塞功能,触发问题通过高精度定时器来解决了,那同步问题如何解决?--进程调度(复习下操作系统基本原理)

cd262a31ea51c2c97a91f22bcce843ad.png

由上面代码可知在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所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(76)

评论列表共有 0 条评论

立即
投稿
返回
顶部