快速业务通道

Linux系统进程间隔定时器Itimer

作者 佚名技术 来源 Linux系统 浏览 发布时间 2012-04-24
示间隔计数器的初始值,而it_value成员表示间隔计数器的当前值.这两个成员都是timeval结构类型的变量,因此其精度可以达到微秒级.

  timeval与jiffies之间的相互转换

  间隔定时器的间隔计数器的内部表示方式与外部表现方式互不相同,因此有必要实现以微秒为单位的timeval结构和为时钟滴答次数单位的 jiffies之间的相互转换.为此,Linux在kernel/itimer.c中实现了两个函数实现二者的互相转换——tvtojiffies()函数和jiffiestotv()函数.它们的源码如下:

  static unsigned long tvtojiffies(struct timeval *value)

  {

  unsigned long sec = (unsigned) value->tv_sec;

  unsigned long usec = (unsigned) value->tv_usec;

  if (sec > (ULONG_MAX / HZ))

  return ULONG_MAX;

  usec = 1000000 / HZ - 1;

  usec /= 1000000 / HZ;

  return HZ*sec usec;

  }

  static void jiffiestotv(unsigned long jiffies, struct timeval *value)

  {

  value->tv_usec = (jiffies % HZ) * (1000000 / HZ);

  value->tv_sec = jiffies / HZ;

  }

  7.7.2 真实间隔定时器ITIMER_REAL的底层运行机制

  间隔定时器ITIMER_VIRT和ITIMER_PROF的底层运行机制是分别通过函数do_it_virt()函数和do_it_prof()函数来实现的,这里就不再重述(可以参见7.4.3节).

  间隔定时器ITIMER_REAL本质上与内核动态定时器并无区别.因此内核实际上是通过内核动态定时器来实现进程的ITIMER_REAL间隔定时器的.为此,task_struct结构中专门设立一个timer_list结构类型的成员变量real_timer.动态定时器real_timer 的函数指针function总是被task_struct结构的初始化宏INIT_TASK设置为指向函数it_real_fn().如下所示(include/linux/sched.h):

  #define INIT_TASK(tsk)

  ……

  real_timer: {

  function: it_real_fn

  }

  ……

  }

  而real_timer链表元素list和data成员总是被进程创建时分别初始化为空和进程task_struct结构的地址,如下所示(kernel/fork.c):int do_fork(……)

  {

  ……

  p->it_real_value = p->it_virt_value = p->it_prof_value = 0;

  p->it_real_incr = p->it_virt_incr = p->it_prof_incr = 0;

  init_timer(&p->real_timer);

  p->real_timer.data = (unsigned long)p;

  ……

  }

  当用户通过setitimer()系统调用来设置进程的ITIMER_REAL间隔定时器时,it_real_incr被设置成非零值,于是该系统调用相应地设置好real_timer.expires值,然后进程的real_timer定时器就被加入到内核动态定时器链表中,这样该进程的 ITIMER_REAL间隔定时器就被启动了.当real_timer定时器到期时,它的关联函数it_real_fn()将被执行.注意!所有进程的 real_timer定时器的function函数指针都指向it_real_fn()这同一个函数,因此it_real_fn()函数通过其参数来识别是哪一个进程,为此它将unsigned long类型的参数p解释为进程task_struct结构的地址.该函数的源码如下(kernel/itimer.c):

  void it_real_fn(unsigned long __data)

  {

  struct task_struct * p = (struct task_struct *) __data;

  unsigned long interval;

  send_sig(SIGALRM, p, 1);

  interval = p->it_real_incr;

  if (interval) {

  if (interval > (unsigned long) LONG_MAX)

  interval = LONG_MAX;

  p->real_timer.expires = jiffies interval;

  add_timer(&p->real_timer);

  }

  }

  函数it_real_fn()的执行过程大致如下:

  (1)

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号