Linux it_real_fn进程间隔定时器real与ITIMER_REALITIMER_REAL是Linux进程级间隔定时器之一对应setitimer系统调用的ITIMER_REAL类型。它使用实时时钟real time递减到期时向进程发送SIGALRM信号。it_real_fn是内核中维护该定时器的核心回调函数。每个进程的signal_struct中维护了与ITIMER_REAL相关的字段struct signal_struct {...struct hrtimer real_timer;ktime_t it_real_incr;...};real_timer是一个hrtimer到期时调用it_real_fn。it_real_incr保存定时器的间隔值用于在到期后重新加载。ITIMER_REAL的初始化通过setitimer系统调用触发最终调用do_setitimerint do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue){struct task_struct *tsk current;struct hrtimer *timer;ktime_t expires;switch (which) {case ITIMER_REAL:if (ovalue)*ovalue tsk-signal-it_real_incr;timer tsk-signal-real_timer;if (value-it_value.tv_sec 0 value-it_value.tv_usec 0) {hrtimer_try_to_cancel(timer);return 0;}tsk-signal-it_real_incr timeval_to_ktime(value-it_interval);expires timeval_to_ktime(value-it_value);hrtimer_start(timer, expires, HRTIMER_MODE_REL);break;...}return 0;}do_setitimer将用户态的itimerval转换为ktime_t调用hrtimer_start启动real_timer。定时器的到期模式为HRTIMER_MODE_REL相对当前时间。间隔值存入it_real_incr以备后续重新加载。it_real_fn是hrtimer到期后的回调函数定义如下enum hrtimer_restart it_real_fn(struct hrtimer *timer){struct signal_struct *sig container_of(timer, struct signal_struct, real_timer);struct pid *leader_pid sig-pids[PIDTYPE_TGID];struct task_struct *p;trace_itimer_expire(ITIMER_REAL, sig);rcu_read_lock();p pid_task(leader_pid, PIDTYPE_TGID);if (p ! NULL) {__group_send_sig_info(SIGALRM, SEND_SIG_PRIV, p);}rcu_read_unlock();if (sig-it_real_incr ! 0) {hrtimer_forward(timer, hrtimer_cb_get_time(timer), sig-it_real_incr);return HRTIMER_RESTART;}return HRTIMER_NORESTART;}it_real_fn首先通过container_of从hrtimer指针回溯到signal_struct。然后通过pid_task找到线程组leader向其发送SIGALRM信号。__group_send_sig_info确保信号发送到整个线程组tgid而非仅当前线程。若it_real_incr非零即设置了间隔值则调用hrtimer_forward将定时器向前推进一个间隔周期返回HRTIMER_RESTART让hrtimer框架重新插入红黑树。hrtimer_forward的语义是以当前时间为基准将timer的expires增加n个间隔直至大于等于当前时间保证不会丢失ticku64 hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval){u64 orun 1;ktime_t delta ktime_sub(now, timer-node.expires);if (delta 0)return 0;if (interval hrtimer_resolution)interval hrtimer_resolution;orun ktime_divns(delta, ktime_to_ns(interval));timer-node.expires ktime_add(timer-node.expires,times64_orun * interval);return orun;}hrtimer_forward返回超期运行的次数orun。若定时器被阻塞了多个周期orun可告知调用者跳过了多少个信号。但it_real_fn自身并未处理orun返回值——这意味着如果进程在较长一段时间内未调度可能导致多个SIGALRM信号被合并为单一信号发出。ITIMER_REAL的读取通过do_getitimer实现返回当前剩余时间和间隔值int do_getitimer(int which, struct itimerval *value){struct task_struct *tsk current;ktime_t rem;switch (which) {case ITIMER_REAL:rem hrtimer_get_remaining(tsk-signal-real_timer);if (rem 0)rem 0;*value (struct itimerval) {.it_interval ktime_to_timeval(tsk-signal-it_real_incr),.it_value ktime_to_timeval(rem),};break;...}return 0;}hrtimer_get_remaining返回hrtimer剩余到期时间可实现精度达纳秒级。因此ITIMER_REAL的精度由底层hrtimer决定而非传统timer wheel的jiffy精度。ITIMER_REAL与alarm系统调用的关系紧密alarm(seconds)本质上等价于setitimer(ITIMER_REAL, ...)。内核中alarm系统调用的实现最终调用do_setitimer完成定时器设置。ITIMER_REAL与ITIMER_VIRTUAL和ITIMER_PROF的区别在于时钟源ITIMER_REAL使用CLOCK_REALTIME墙上时间进程即使处于睡眠状态定时器也会继续递减ITIMER_VIRTUAL仅统计用户态CPU时间ITIMER_PROF统计用户态内核态CPU时间。这种差异反映在底层分别使用real_timerhrtimer、cpu_timers[CPUCLOCK_VIRT]和cpu_timers[CPUCLOCK_PROF]三种不同的机制。在进程fork时子进程不会继承父进程的ITIMER_REAL定时器。fork系统调用的copy_process中会将子进程signal_struct中的real_timer重置为未激活状态ITIMER_REAL仅在当前进程上下文有效。