目录:
-
一、如何组织定时任务?
-
定时器收网络IO处理造成误差特别大,该怎么处理?
-
用何种数据机构存储定时器?
-
红黑树如何解决相同时间的key值的?
-
最小堆
-
时间轮
-
一个帮助理解单层级时间轮的例子
-
如何解决空推进的问题?
-
为什么多线程使用时间轮
-
设计哪些接口,如何设计?
-
满足哪些条件才能作为定时器的数据结构?
-
二、定时的方法有哪些?
-
究竟什么是定时?
-
三、总结
一、如何组织定时任务?
首先,定时器组件通常和网络组件一起工作。举个最简单的例子来说:
int event=epoll_wait(epfd,ev,nev,timeout);
timeout作为参数值,<0为一直阻塞,=0相当于非阻塞检测双端队列就绪情况0代表立刻返回,>0数值表示最长阻塞的时间。在时间上需要应对的问题填入epoll_wait函数,就可以兼顾网络事件的处理和定时任务的处理。
定时器收网络IO处理造成误差特别大,该怎么处理?
-
nginx,redis中通过定时信号去处理+epoll_wait解决,nginx_timer_revolusion()函数定时发送时间信号会打断epoll_wait()的处理,让它尽快的处理定时事件,从而解决了误差较大的问题。很明显,如果网络IO处理事件时,会造成一定的误差。定时任务事件处理=epoll_wait处理时间+网络事件处理时间。
//第一种:通过发送定时信号去打断epoll_wait函数
while(!quit)
{
int now=get_now_time();//单位:ms
int timeout=get_nearest_time()-now;
if(timeout<0)
timeout=0;
int nevent=epoll_wait(epfd,ev,nev,timeout);
for(int i=0;i<nevent;i++)
{
//网络事件处理
}
update_timer();、//时间事件处理
}
单独开启一个线程,去处理定时任务。