设为首页 加入收藏

TOP

Linux的动态定时器--时间轮
2014-11-24 12:25:58 来源: 作者: 【 】 浏览:0
Tags:Linux 动态 定时器 --时间

Linux的定时器—有时也称为动态定时器或内核定时器—是管理内核时间的基础。定时器是一种软件功能,即允许在将来的某个时刻,函数在给定的时间间隔用完时被调用。注意的是定时器并不会周期运行,它在超时后就自行销毁,这也是定时器被称为动态定时器的一个原因。动态定时器不断地创建和销毁,而且它的运行次数也不受限制。


定时器在内核代码中属于一个基础组件。要想完全弄清楚linux2.6中内核定时器的实现,得先从初始化开始。


在start_kernel(void)-->init_timers(void)


timer_cpu_notify(&timers_nb,(unsigned long)CPU_UP_PREPARE,


(void*)(long)smp_processor_id());


中执行


init_timers_cpu(cpu) //初始化本cpu中的timers


初始化的主要代码是:


这段代码的主体是basebase的定义是:structtvec_base *base;


这个tvec_base是动态定时器的主要数据结构,每个cpu上有一个,它包含相应cpu中处理动态定时器需要的所有数据。为简化分析仅考虑单cpu。给出这个数据机构:


其中,timer_list是具体定时器的结构体(后面再具体看timer_list结构体);上面包含tv1tv2tv3tv4tv5;内核定时器的巧妙设计就在于此。


从这个定义看到,tv1就是长度为256的数组,数组成员是list_head;同样的,tv2tv3tv4tv5都是长度为64的数组,数组成员是list_headList_head就是linux内核代码中广泛使用的双向链表。在阻塞和非阻塞中的等待队列时就看到了list_head的应用。那么,tv1-tv5都是数组+链表的实现,其实hash的有一种简单实现就是数组+链表的组合,那么这几个就有些hash的味道,具体是不是,还要分析道后面才知道。


再回到前面的初始化中,


for(j = 0; j < TVN_SIZE; j++) {


INIT_LIST_HEAD(base->tv5.vec+ j);


INIT_LIST_HEAD(base->tv4.vec+ j);


INIT_LIST_HEAD(base->tv3.vec+ j);


INIT_LIST_HEAD(base->tv2.vec+ j);


}


for(j = 0; j < TVR_SIZE; j++)


INIT_LIST_HEAD(base->tv1.vec+ j);


tv1-tv55个结构体中的数组中每个list_head进行初始化。


base->timer_jiffies= jiffies;


base->next_timer= base->timer_jiffies;


base中的timer_jiffiesnext_timer都初始化为jiffies




初始化完成后,在init_timers函数的第二个重要的步骤是:


open_softirq(TIMER_SOFTIRQ,run_timer_softirq);




下面来看具体定时器的初始化和添加操作:



初始化的函数:


初始化的宏定义:


定时器的添加:


Timer_list结构体的定义:



】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Linux设备驱动下的tasklet 下一篇Linux2.6定时器的时间轮算法分析

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·python数据分析岗的 (2025-12-25 10:02:21)
·python做数据分析需 (2025-12-25 10:02:19)
·成为一个优秀的pytho (2025-12-25 10:02:16)
·Java后端面试实习自 (2025-12-25 09:24:21)
·Java LTS版本有哪些 (2025-12-25 09:24:18)