Bootstrap

Webserver(定时器实现)

网络编程中除了处理IO事件之外,定时事件也同样不可或缺,如定期检测一个客户连接的活动状态、游戏中的技能冷却倒计时以及其他需要使用超时机制的功能。我们的服务器程序中往往需要处理众多的定时事件,因此有效的组织定时事件,使之能在预期时间内被触发且不影响服务器主要逻辑,对我们的服务器性能影响特别大。
我们的web服务器也需要这样一个时间堆,定时剔除掉长时间不动的空闲用户,避免他们占着茅坑不拉屎,耗费服务器资源。
一般的做法是将每个定时事件封装成定时器,并使用某种容器类数据结构将所有的定时器保存好,实现对定时事件的统一管理。常用方法有排序链表、红黑树、时间堆和时间轮。这里使用的是时间堆。
时间堆的底层实现是由小根堆实现的。小根堆可以保证堆顶元素为最小的。
1、为什么要用定时器?
由于非活跃连接占用了连接资源,严重影响服务器的性能,通过实现一个服务器定时器,处理这种非活跃连接,释放连接资源。
2、说一下定时器的工作原理?
由于定时器的触发是由于时间到了,因此只有时间最短的定时器会首先被触发,通过这个原理,我们可以采用 最小堆,将按时间顺序排序,堆顶元素是时间最短的定时器,因此只要判断堆顶元素是否被触发即可。只有堆顶定时器的时间到了,才会到其他时间较晚的定时器的时间。
定时器利用结构体将Http连接对应的fd、有效期、回调函数等封装起来。
服务器主循环每建立一个连接则为该连接创建一个定时器节点,插入到最小堆中,主循环通过GetNextTick清除超时的节点,关闭对应连接,释放连接资源,然后获取最先要超时的连接的 超时的时间,并设置下一次epollwait0)的超时时间为该时间。当已建立的连接有I0事件时,延长这个连接的超时时间,调整最小堆。
3、说一下最小堆?说一下时间复杂度和工作原理?
时间复杂度:添加:O(logn),删除:O(logn)
工作原理:
将所有定时器中超时时间最小的一个定时器的超时值,作为定时任务处理函数的定时值。这样,一旦定时任务处理函数被调用,超时时间最小的定时器必然到期,我们就可以在定时任务处理函数中处理该定时器。
然后,再次从剩余的定时器中找出超时时间最小的一个(堆),并将这段最小时间设置为下一次定时任务处理函数的定时值。如此反复,就实现了较为精确的定时。
;