内核延迟

来源:互联网 发布:期货蝶式套利软件 编辑:程序博客网 时间:2024/06/10 02:52

1. linux内核定时器

内核定时器把操作推迟到某个确定的时间段之后执行。

1.时钟中断进行由系统定时硬件周期性的时间间隔产生,间隔(即频率)由内核根据Hz常数决定,可配置为50-1200,x86平台默认值为1000,即每秒产生1000次中断。每次时钟中断产生时,全局变量jiffies(unsigned long)就会加1,它记录着自linux启动之后共产生的时钟中断的次数。

作用:把一些例行的和需要定时执行的程序放在时钟中断中;利用时钟中断协助主程序完成定时、延时等操作,但其定时精度不高!

例如: unsigned long j=jiffies+x_delay*Hz

            while(jiffies<j)

{

//do nothing

}

//延时x_delay秒

 

2.内核定时器

用于控制某个函数(定时器处理函数)在未来的某个特定时间执行。

内核定时器注册的处理函数只执行一次(不是循环执行的)。

它可用于驱动程序当中。

内核定时器被组织成双向链表,并使用struct timer_list来描述一个内核定时器!

timer_list结构描述:

struct timer_list{

  struct list_head entry;//内核使用,形成定时器链表,由内核初始化

  unsigned long expires;//超时的jiffies值,在什么时候超时,自己设定

  void (*function)(unsigned long);//超时处理函数,超时后执行什么函数,自己设定

  unsigned long data;//超时处理函数参数,无符号长整形,自己设定

  struct tvec_base *base;//内核使用,由内核初始化

};

相关函数:

void init_timer(struct timer_list *timer)  初始化定时器队列结构,仅对entry和八色

vod add_timer(struct timer_list *timer)  启动定时器

int del_timer(struct timer_list *timer) 启动定时器前将它删除,因为在超时后系统会自动将它删除。

 

例子--编写内核模块定时器:

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/timer.h>  /*timer*/
#include <asm/uaccess.h>  /*jiffies*/

MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Xie");
MODULE_DESCRIPTION("Timer Module");
MODULE_ALIAS("timer module");

struct timer_list timer;//定义内核定时器

void timer_function(int para)//作为内核定时器的处理函数,此处para为形参

而实际值由timer.data传递过来。

{

     printk("<0>Timer Expired and para is %d !!\n",para); //输出data参数
}

int timer_init()  //模块初始化函数用于module_init()
{
 init_timer(&timer);//初始化定时器链表
 timer.data = 5;//参数为5,用于timer.function
 timer.expires = jiffies + (20 * HZ);//设置定时时间为20秒
 timer.function = timer_function;//设置操作函数
 add_timer(&timer);//启动定时器

//注意以上几个函数的参数均为指针类型的,所以用&取地址
 return 0;
}

void timer_exit()
{
 del_timer( &timer );
}

module_init(timer_init);
module_exit(timer_exit);

 

#insmod之后会打印出:Timer Expired and para is 20

 

通过此例对内核定时器有了一个初步的了解。

2. 忙等待

mdelay, udelay ndelay

3. 软中断和tesklet

内核定时器和tasklet都是建立在软中断之上的

软中断是一组静态定义的下半部接口,有32个。可以在所有的处理器上同时执行---即使两个类型相同也可以。

tasklet是一种基于软中断实现的灵活性强、动态创建的下半部机制。

2个不同类型tasklet可以在不同的处理器上同时执行----但类型相同的tasklet不能同时执行。

4. 工作队列

先对要推后执行的工作队列排队,稍后再进程上下文中执行他们。通过一个内核线程去调用它。

5. completion

wait_for_completion 等待一个非中断事件

原创粉丝点击