Chinaunix首页 | 论坛 | 博客
  • 博客访问: 306693
  • 博文数量: 27
  • 博客积分: 1933
  • 博客等级: 上尉
  • 技术积分: 884
  • 用 户 组: 普通用户
  • 注册时间: 2011-01-04 23:34
文章分类

全部博文(27)

文章存档

2013年(3)

2011年(24)

分类:

2013-01-04 14:06:41

原文地址:定时器(timer) 作者:add358

  1 定时器用途
  内核定时器用于在未来的指定时间点上执行某个函数;如果添加定时器时,指定的时间比系统时间要早,那么,系统将会在下一个"滴答“启动该定时器。

  2 使用定时器注意事项
  内核定时器基本上会在"软件中断"上下文中运行,所以定时器函数要注意以原子地运行;且定时器始终会在调度它的同一CPU上运行。另外需要遵守以下规则:
  1. * 不允许访问用户空间;
  2. * 不允许访问current指针;
  3. * 不能执行休眠或调度。
  所有处于进程上下文之外的程序都要遵守这些规则。
 
  3 内核环境判断
  内核提供两个API来判断中断上下文和原子上下文
  1. #include <linux/hardirq.h>
  2. int in_interrupt(); /* 如果在中断上下文,则返回非零值 */
  3. int in_atomic();    /* 如果在原子上下文,则返回非零值 */
  4 定时器结构
  1. #include
  2. struct timer_list{
  3.    /* 省略一些成员,只列出可由定时器代码以外的代码访问的三个成员 */
  4.    unsigned long expires;
  5.    void (*function)(unsigned long);
  6.    unsigned long data;
  7. };
  5 几个重要的定时器接口
  1. #include <linux/timer.h>

  2. void init_timer(struct timer_list *timer); /* 初始化定时器 */
  3. struct timer_list TIMER_INITIALIZER(_function, _expires, _data);/* 宏初始化并指定相关成员值*/

  4. void add_timer(struct timer_list *timer); /* 向内核添加定时器 */
  5. int del_timer(struct timer_list *timer); /* 移除定时器 */

  6 示例代码
  1. #include <linux/init.h>
  2. #include <linux/module.h>
  3. #include <linux/timer.h> /* timer */
  4. #include <linux/hardirq.h> /* in_interrupt(),in_atomic() */

  5. MODULE_LICENSE("Dual BSD/GPL");
  6. MODULE_AUTHOR("Kozo");

  7. struct timer_list timer;

  8. static inline void timer_fn(unsigned long data)
  9. {
  10.     timer.data = jiffies;
  11.     timer.expires = jiffies + 2*HZ;
  12.     add_timer(&timer);  /* 可自我注册 */
  13.     printk(KERN_INFO"---------------------------\n");
  14.     printk(KERN_INFO"jiffies_prior=%ld\n",data);
  15.     printk(KERN_INFO"jiffies_now  =%ld\n",timer.data);
  16.     printk(KERN_INFO"In interrupt context: %c\n",in_interrupt()?'Y':'N');
  17.     printk(KERN_INFO"Is in atomic : %c\n", in_atomic()?'Y':'N');
  18. }

  19. static __init int timer_init(void)
  20. {
  21.     init_timer(&timer);
  22.     timer.data = jiffies;
  23.     timer.function = timer_fn;
  24.     timer.expires = jiffies - 10; /* 验证指定的时间比系统时间早时,在下一个"滴答"执行 */
  25.     //timer.expires = jiffies + 2*HZ;

  26.     add_timer(&timer);
  27.     printk(KERN_INFO"In interrupt context: %c\n",in_interrupt()?'Y':'N');
  28.     printk(KERN_INFO"Is in atomic : %c\n", in_atomic()?'Y':'N');

  29.     return 0;
  30. }
  31. static __exit void timer_exit(void)
  32. {
  33.     del_timer(&timer);
  34. //    del_timer_sync(&timer);  /* 用于在SMP系统上避免竞态 */
  35. }
  36. module_init(timer_init);
  37. module_exit(timer_exit);
 7 输出结果
 
  从输出结果可以看出,当第一次注册定时器后,确实在下一个"滴答"启动该定时器,往后便每2秒启动一次。


注:转载时请注时出自:add358.blog.chinaunix.net
阅读(2864) | 评论(0) | 转发(0) |
0

上一篇:工作队列

下一篇:延迟操作

给主人留下些什么吧!~~