内核中的定时器

使用内核定时器的场景:

如果我们需要在将来的某个时间点上来执行某个动作,同时在这个时间点到来之前并不会阻塞当前进行的运行的话,我们可以通过内核定时器来实现。通过使用内核定时器,内核会在这个时间到达时(当然内核中的时间是用时钟中断数来表示的,即内核通过比较当前的jiffies中的值与我们定义的那个时钟中断数,来判断是否到时),来执行我们定义的函数,这样可以实现在一个进程中用来实现多个任务。

   在内核中用 struct timer_list 来表示一个内核定时器,这个struct timer_list可以告诉内核我们什么时候执行我们的函数。

   struct timer_list

   {

      struct list_head entry ; // 内核将内核定时器以双链表的形式组织起来;

      unsigned long expires; // 用于存放函数被启动的时间;

      void (*function)(unsigned long);  // 用于存放我们自己定义的函数;

      unsigned long data ;   // 用于存放传递给自定义函数的参数;

      .

      .

      .

   }

   内核定时器的静态分配及初始化

  


     可知,内核通过 DEFINE_TIMER(timer_name, function, expries, data)宏就可以完成一个 struct timer_list定时器的定义以及初始化。

      timer_name :为 struct timer_list 类型的变量名;

      function   : 函数名;

      expries    : jiffiers + n 未来的时钟中断数;

      data       : 传递给function函数的参数;

  

    动态分配内核定时器;

    所谓的动态分配定时器,是指进程在运行时再分配内核定时器,而不是在编译阶段进分配了内核定时器。

    动态分配内核定时器的做法:

{
     struct timer_list mytimer;
     
     init_timer(&mytimer);
     
     mytimer.expries = jiffies + 100;
     
     mytimer.function = myfunction;
     
     mytimer.data = mydata;
}

   由以上的代码可知,动态分配定时器以后,需要我们进行手动的初始化设置。

   上面代码中的 init_timer()也是一个宏定义,其所做的主要工作是:

               mytimer.entry.prev = NULL;

               mytimer.entry.next = NULL;


   当我们分配了一个内核定时器以后需要将其加入到内核中的定时器链表中,定时器才会起作用。

   将一个定时器加入到内核定时器链表中的方法为:

   void add_timer(struct timer_list *timer);

   更改一个内核定时器中的自定义函数的方法:

   setup_timer(timer, function, data ) 这也是一个宏定义,原型为:

  

  在修改内核定时器的定时时间时,通过下面这个接口来判断内核定时器实在激活状态,还是在非激活状态:

    int timer_pending( struct timer_list *timer );

 


   如果内核定时器中处于激活状态,可以通过下面这个函数来更改内核定时器的时间

   int mod_timer(struct timer_list *timer, unsigned int expries);

  


    如果内核定时器处于非激活状态,可以通过下面这个函数来修改它的时间:

    int mod_timer_pending(struct timer_list *timer, unsigned int expries )

   


内核定时器的删除操作:


   int del_timer( struct timer_list *timer ) 用于删除一个定时器;

  


   int del_timer_sync( struct timer_list *timer ) 也是用于删除一个定时器;

  

  del_timer() 与 del_timer_sync()函数的不同:

  del_timer_sync()函数会检测CPU上是否还有其他地方在使用这个将要被删除的内核定时器,如果有的话,等待这个内核定时器被用完然后在删除;

  del_timer()还直接删除所要删除的内核定时器;

  所以一般建议优先使用del_timer_sync()函数;

总结:

       DEFINE_TIMER(timer_name, function, expries, data);

       init_timer(struct timer_list *timer);

       add_timer(struct timer_list *timer);

       timer_pending(struct timer_list *timer);

       mod_timer(struct timer_list *timer, unsigned int expries);

       mod_timer_pending(struct timer_list *timer, unsigned int expries);

       del_timer(struct timer_list *timer);

       del_timer_sync(struct timer_list * timer);


时间: 2025-01-11 21:44:20

内核中的定时器的相关文章

Linux内核中的jiffies及其作用介绍及jiffies等相关函数详解

在LINUX的时钟中断中涉及至二个全局变量一个是xtime,它是timeval数据结构变量,另一个则是jiffies,首先看timeval结构struct timeval{time_t tv_sec; /***second***/susecond_t tv_usec;/***microsecond***/}到底microsecond是毫秒还是微秒?? 1秒=1000毫秒(3个零),1秒=1000 000微秒(6个零),1秒=1000 000 000纳秒(9个零),1秒=1000 000 000

内核中led触发器实例【转】

本文转载自:http://blog.csdn.net/yuanlulu/article/details/6438847 ============================================作者:yuanluluhttp://blog.csdn.NET/yuanlulu 版权没有,但是转载请保留此段声明============================================ gpio-led框架 /driver/leds/leds-gpio.c下实现了gpio-

向linux内核中添加外部中断驱动模块

本文主要介绍外部中断驱动模块的编写,包括:1.linux模块的框架及混杂设备的注册.卸载.操作函数集.2.中断的申请及释放.3.等待队列的使用.4.工作队列的使用.5.定时器的使用.6.向linux内核中添加外部中断驱动模块.7.完整驱动程序代码.linux的内核版本为linux2.6.32.2. 一.linux模块的框架以及混杂设备相关知识 1.内核模块的框架如下图所示,其中module_init()(图中有误,不是modules_init)只有在使用insmod命令手动加载模块时才会被调用,

Linux内核中的软中断、tasklet和工作队列详解

[TOC] 本文基于Linux2.6.32内核版本. 引言 软中断.tasklet和工作队列并不是Linux内核中一直存在的机制,而是由更早版本的内核中的"下半部"(bottom half)演变而来.下半部的机制实际上包括五种,但2.6版本的内核中,下半部和任务队列的函数都消失了,只剩下了前三者. 介绍这三种下半部实现之前,有必要说一下上半部与下半部的区别. 上半部指的是中断处理程序,下半部则指的是一些虽然与中断有相关性但是可以延后执行的任务.举个例子:在网络传输中,网卡接收到数据包这

Linux内核中kzalloc函数详解

***************************************************************************************************************************作者:EasyWave                                                                                 时间:2013.02.06 类别:Linux 内核驱动源码分析    

在linux内核中获得比jiffies精度更高的时间值【转】

转自:http://blog.chinaunix.net/uid-20672257-id-2831219.html 内核一般通过jiffies值来获取当前时间.尽管该数值表示的是自上次系统启动到当前的时间间隔,但因为驱动程序的生命期只限于系统的运行期 (uptime),所以也是可行的.驱动程序利用jiffies的当前值来计算不同事件间的时间间隔. 硬件给内核提供一个系统定时器用以计算和管理时间,内核通过编程预设系统定时器的频率,即节拍率(tick rate),每一个周期称作一个tick(节拍).

linux内核中的时间接口

时钟中断:是硬件中的定时器以固定的时间产生一次中断. 时钟中断频率:1s中的时钟中断次数: 我们可以通过更改相应的配置,来改变一个系统的时钟中断频率. 先来看看X86平台上的时钟中断频率: 有以上可知,内核通过使用 HZ 宏来表示在内核中的时钟频率为CONFIG_HZ,当然我们就可以通过改变 相应的体系结构中的config文件中CONFIG_HZ的值,来调整内核中的时钟频率值. 如果 CONFIG_HZ=1000的话,内核通过时钟频率所能测出的时间的分辨率为 1ms. linux系统中,通过使用

游戏中的定时器

写在前面 游戏中处处都有定时器,基本上每个逻辑部分我们都能看到定时器的影子.如果翻看一下以前网上流传的一些MMO的代码,比如mangos的,比如大唐的,比如天龙的,我们都可以看到形形色色的定时器实现. 在以前,很多程序员用起来C++还都是在用C with Object,以前的C++写callback也好异步也好总是感觉哪里不对劲的样子,所以网上流传的那种线上服务器的代码,一般都是往主循环里硬塞定时器逻辑. 定时器在很多能参考到的代码里都是逻辑和底层不做区分的,这样就会导致一些问题.一方面,底层的

Linux内核中的软中断、tasklet和工作队列具体解释

[TOC] 本文基于Linux2.6.32内核版本号. 引言 软中断.tasklet和工作队列并非Linux内核中一直存在的机制,而是由更早版本号的内核中的"下半部"(bottom half)演变而来. 下半部的机制实际上包含五种,但2.6版本号的内核中.下半部和任务队列的函数都消失了,仅仅剩下了前三者. 介绍这三种下半部实现之前.有必要说一下上半部与下半部的差别. 上半部指的是中断处理程序,下半部则指的是一些尽管与中断有相关性可是能够延后运行的任务. 举个样例:在网络传输中.网卡接收