Linux系统进程间隔定时器Itimer
示间隔计数器的初始值,而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 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |