当前位置: 首页 > 工具软件 > itimer > 使用案例 >

linux下itimer定时器的应用

齐承运
2023-12-01

一、定时器操作

Linux 为每一个进程提供了 3 个 setitimer 间隔计时器:

1. ITIMER_REAL:减少实际时间,到期的时候发出 SIGALRM 信号。

2. ITIMER_VIRTUAL:减少有效时间 (进程执行的时间),产生 SIGVTALRM 信号。

3. ITIMER_PROF:减少进程的有效时间和系统时间 (为进程调度用的时间)。这个经常和上面一个使用用来计算系统内核时间和用户时间。产生 SIGPROF 信号。

    所谓 REAL 时间,即我们人类自然感受的时间,英文计算机文档中也经常使用 wall-clock 这个术语。说白了就是我们通常所说的时间,比如现在是下午 5 点 10 分,那么一分钟的 REAL 时间之后就是下午 5 点 11 分。

    VIRTUAL 时间是进程执行的时间,Linux 是一个多用户多任务系统,在过去的 1 分钟内,指定进程实际在 CPU 上的执行时间往往并没有 1 分钟,因为其他进程会被 Linux 调度执行,在那些时间内,虽然自然时间在流逝,但指定进程并没有真正的运行。VIRTUAL 时间就是指定进程真正的有效执行时间。比如 5 点 10 分开始的 1 分钟内,进程 P1 被 Linux 调度并占用 CPU 的执行时间为 30 秒,那么VIRTUAL 时间对于进程 P1 来讲就是 30 秒。此时自然时间已经到了 5 点 11 分,但从进程 P1 的眼中看来,时间只过了 30 秒。

    PROF 时间比较独特,对进程 P1 来说从 5 点 10 分开始的 1 分钟内,虽然自己的执行时间为 30 秒,但实际上还有 10 秒钟内核是在执行 P1 发起的系统调用,那么这 10 秒钟也被加入到 PROF 时间。这种时间定义主要用于全面衡量进程的性能,因为在统计程序性能的时候,10 秒的系统调用时间也应该算到 P1 的头上。这也许就是 PROF 这个名字的来历吧。


取值

含义

信号发送

ITIMER_REAL

定时真实时间,与alarm类型相同。

SIGALRM

ITIMER_VIRT

定时进程在用户态下的实际执行时间。

SIGVTALRM

ITIMER_PROF

定时进程在用户态和核心态下
的实际执行时间。

SIGPROF

定时器用到的结构:

 1 /* Type of the second argument to `getitimer' and
 2    the second and third arguments `setitimer'.  */
 3 struct itimerval
 4   {
 5     /* Value to put into `it_value' when the timer expires.  */
 6     struct timeval it_interval;
 7     /* Time to the next timer expiration.  */
 8     struct timeval it_value;
 9   };
10 
11 /* A time value that is accurate to the nearest
12    microsecond but also has a range of years.  */
13 struct timeval
14   {
15     __time_t tv_sec;        /* Seconds.  */
16     __suseconds_t tv_usec;    /* Microseconds.  */
17   };
函数
 1 typedef int __itimer_which_t;
 2 
 3 /* Set *VALUE to the current setting of timer WHICH.
 4    Return 0 on success, -1 on errors.  */
 5 extern int getitimer (__itimer_which_t __which,
 6               struct itimerval *__value) __THROW;
 7 
 8 /* Set the timer WHICH to *NEW.  If OLD is not NULL,
 9    set *OLD to the old value of timer WHICH.
10    Returns 0 on success, -1 on errors.  */
11 extern int setitimer (__itimer_which_t __which,
12               const struct itimerval *__restrict __new,
13               struct itimerval *__restrict __old) __THROW;
二、信号操作
    这里只介绍与定时器相关的操作,具体信号方面的知识,参见《linux中的进程与信号》一文。
 1 /* Get and/or set the action for signal SIG.  */
 2 extern int sigaction (int __sig, const struct sigaction *__restrict __act,
 3               struct sigaction *__restrict __oact) __THROW;
 4 
 5 /* Structure describing the action to be taken when a signal arrives.  */
 6 struct sigaction
 7   {
 8     /* Signal handler.  */
 9 #ifdef __USE_POSIX199309
10     union
11       {
12     /* Used if SA_SIGINFO is not set.  */
13     __sighandler_t sa_handler;
14     /* Used if SA_SIGINFO is set.  */
15     void (*sa_sigaction) (int, siginfo_t *, void *);
16       }
17     __sigaction_handler;
18 # define sa_handler    __sigaction_handler.sa_handler
19 # define sa_sigaction    __sigaction_handler.sa_sigaction
20 #else
21     __sighandler_t sa_handler;
22 #endif
23 
24     /* Additional set of signals to be blocked.  */
25     __sigset_t sa_mask;
26 
27     /* Special flags.  */
28     int sa_flags;
29 
30     /* Restore handler.  */
31     void (*sa_restorer) (void);
32   };

三、程序例子
 1 #include <stdlib.h>
 2 #include <signal.h>
 3 #include <stdio.h>
 4 #include <unistd.h>
 5 #include <time.h>
 6 #include <sys/time.h>
 7 
 8 void adc_read()
 9 {
10     printf("Hello\n");
11 }
12 
13 int main()
14 {
15     struct sigaction act;
16     struct itimerval adc_timer;
17     
18     act.sa_handler = adc_read;
19     sigemptyset(&act.sa_mask);
20     act.sa_flags = 0;
21     sigaction(SIGALRM, &act, NULL);
22     
23     adc_timer.it_value.tv_sec = 20;
24     adc_timer.it_value.tv_usec = 0;
25     adc_timer.it_interval = adc_timer.it_value;
26     /*
27      * Initialize the timer.
28      * Send SIGALRM signal
29      */
30     setitimer(ITIMER_REAL, &adc_timer, NULL); 
31     while(1);
32 }
除例子外代码来自glibc-2.18
 类似资料: