Linux的动态定时器-时间轮

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

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

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


void __init init_timers(void)

{

int err = timer_cpu_notify(&timers_nb, (unsigned long)CPU_UP_PREPARE,

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

init_timer_stats();

BUG_ON(err == NOTIFY_BAD);

register_cpu_notifier(&timers_nb);

open_softirq(TIMER_SOFTIRQ, run_timer_softirq);

}

在timer_cpu_notify(&timers_nb,(unsigned long)CPU_UP_PREPARE,

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

  中执行

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

  初始化的主要代码是:


spin_lock_init(&base->lock);

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);

base->timer_jiffies = jiffies;

base->next_timer = base->timer_jiffies;

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

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


struct tvec_base {

spinlock_t lock;

struct timer_list *running_timer;

unsigned long timer_jiffies;

unsigned long next_timer;

struct tvec_root tv1;

struct tvec tv2;

struct tvec tv3;

struct tvec tv4;

struct tvec tv5;

} ____cacheline_aligned;

最新内容请见作者的GitHub页:http://qaseven.github.io/

时间: 2024-12-22 13:32:28

Linux的动态定时器-时间轮的相关文章

linux下的定时器

简介 这篇文章主要记录我在试图解决如何尽可能精确地在某个特定的时间间隔执行某项具体任务时的思路历程,并在后期对相关的API进行的归纳和总结,以备参考. 问题引出 很多时候,我们会有类似"每隔多长时间执行某项任务"的需求,乍看这个问题并不难解决,实则并不容易,有很多隐含条件需要考虑,诸如:时间精度是多少?时间是否允许出现偏差,允许的偏差是多少,偏差之后如何处理?系统的负载如何?这个程序允许占用的系统资源是否有限制?这个程序运行的硬件平台如何? 为了便于分析,我们锁定题目为"每隔

Linux下实现定时器Timer的几种方法总结_Linux

定时器Timer应用场景非常广泛,在Linux下,有以下几种方法: 1,使用sleep()和usleep() 其中sleep精度是1秒,usleep精度是1微妙,具体代码就不写了.使用这种方法缺点比较明显,在Linux系统中,sleep类函数不能保证精度,尤其在系统负载比较大时,sleep一般都会有超时现象. 2,使用信号量SIGALRM + alarm() 这种方式的精度能达到1秒,其中利用了*nix系统的信号量机制,首先注册信号量SIGALRM处理函数,调用alarm(),设置定时长度,代码

手把手教你写Linux设备驱动---定时器(一)(基于友善之臂4412开发板)

这个专题我们来说下Linux中的定时器. 在Linux内核中,有这样的一个定时器,叫做内核定时器,内核定时器用于控制某个函数,也就是定时器将要处理的函数在未来的某个特定的时间内执行.内核定时器注册的处理函数只执行一次,即不是循环执行的. 如果对延迟的精度要求不高的话,最简单的实现方法如下---忙等待: Unsigned long j = jiffies + jit_delay * HZ; While(jiffies < j) { -- } 下面来说下具体的参数代表的含义: jiffies:全局变

Linux应用层的定时器Timer使用详解【转】

转自:http://blog.csdn.net/wwwtovvv/article/details/8601528 版权声明:本文为博主原创文章,未经博主允许不得转载. linux下定时器的使用 -- alarm() & setitimer(): 1.alarm -------------------------------------------     如果不要求很精确的话,用alarm()和signal()就够了    unsigned int alarm(unsigned int seco

Linux系统调整时区和时间的方法

比如我要吧机器调成太平洋时区,那么我可以输入以下的命令,我们创建一个Link文件来指明是Pacific Time: cd /etc/ rm –r localtime sudo ln -s /usr/share/zoneinfo/US/Pacific localtime 调节完时区之后,接下来就是设置时间,设置在刚才的时区设定下的时间,我们这里设置的是24时制: date +%T -s "14:41:00" 本文URL地址:http://www.bianceng.cn/OS/Linux/

Spring Quartz如何动态配置时间(1)

1. 目的:动态设置时间,触发相应的任务 2. 系统架构为 struts + spring + hibernate 3. 实现步骤: 在页面上设置时间: 将时间转换为Unix Cron Expression: 将转换后的时间规则表达式记录到数据库中(也可以写入xml文件中,这里是项目需要记录入数据库中): 从数据库中得到相应的时间规则表达式: 更新您的任务触发器的时间设置: RESCHEDULE THE JOB.; - ) 4. 具体实现细节: 1) 在页面上设置时间 根据具体的业务需求,设置时

关于Linux文档的时间

在Linux相关岗位的面试中,经常会问到文档时间的问题.Linux文档的时间一般分三种:Access time-atime(访问时间).Modification time-mtime(内容修改时间).status-ctime(状态时间) mtime可以通过ls -l命令显示,表示文档内容最后被修改的时间. atime可以通过ls -lu命令显示,表示文档最后被访问的时间. ctime可以通过ls -lc命令显示,表示文档属性最后被修改的时间. 示例说明,以下示例均已Ubuntu 10.04.4为

linux手动调整日期时间

  演示系统及适用范围 演示系统:Centos6.4 适用范围:linux centos修改日期 在终端执行以下确定并确定,即可把当前系统日期修改为1998年7月11日 01.date -s 07/11/98 centos修改时间 在终端执行以下确定并确定,即可把当前系统时间修改为22点40分0秒 01.date -s 22:40:00 centos修改日期时间注意事项 在centos系统启动时,Linux系统会将时间从CMOS读到当前系统变量中,而我们修改的时间都是通过修改系统的时间实现的,为

quartz 定时器 时间配置

问题描述 quartz 定时器 时间配置 求教各位大神,定时任务每周6的凌晨1点运行跑7个小时,这个该怎么配呢? 解决方案 0 0 1 ? * SUN 如上可以控制什么时间点执行你的程序,程序运行多长则取决于你的程序代码来记时控制 解决方案二: 能不能执行7小时,是你程序控制的,不是quartz 控制的事情. 开始执行时,程序及时,一旦7小时,停止 解决方案三: quartz的时间配置 这些星号由左到右按顺序代表 : * * * * * * * 格式: [秒] [分] [小时] [日] [月]