Linux setitimer定时器使用

3330阅读 0评论2014-06-19 abin9630
分类:LINUX

在网上查看到一份关于贪吃蛇的实现代码,其中使用到 setitimer函数来触发屏幕的刷新打印

之前对该函数不甚了解,因此顺便学习下

首先是关于其的man资料。说实话我没有太看懂其使用,至少是对于  it_interval参数作用不了解

点击(此处)折叠或打开

  1. NAME
  2.        getitimer, setitimer - get or set value of an interval timer

  3. SYNOPSIS
  4.        #include <sys/time.h>

  5.        int getitimer(int which, struct itimerval *curr_value);
  6.        int setitimer(int which, const struct itimerval *new_value,
  7.                      struct itimerval *old_value);

  8. DESCRIPTION
  9.        The system provides each process with three interval timers, each decrementing in a distinct time domain. When any timer expires, a signal
  10.        is sent to the process, and the timer (potentially) restarts.

  11.        ITIMER_REAL decrements in real time, and delivers SIGALRM upon expiration.

  12.        ITIMER_VIRTUAL decrements only when the process is executing, and delivers SIGVTALRM upon expiration.

  13.        ITIMER_PROF decrements both when the process executes and when the system is executing on behalf of the process. Coupled with
  14.                       ITIMER_VIRTUAL, this timer is usually used to profile the time spent by the application in user and kernel space. SIGPROF
  15.                       is delivered upon expiration.

  16.        Timer values are defined by the following structures:

  17.            struct itimerval {
  18.                struct timeval it_interval; /* next value */
  19.                struct timeval it_value; /* current value */
  20.            };

  21.            struct timeval {
  22.                time_t tv_sec; /* seconds */
  23.                suseconds_t tv_usec; /* microseconds */
  24.            };

  25.        The function getitimer() fills the structure pointed to by curr_value with the current setting for the timer specified by which (one of
  26.        ITIMER_REAL, ITIMER_VIRTUAL, or ITIMER_PROF). The element it_value is set to the amount of time remaining on the timer, or zero if the
  27.        timer is disabled. Similarly, it_interval is set to the reset value.

  28.        The function setitimer() sets the specified timer to the value in new_value. If old_value is non-NULL, the old value of the timer is
  29.        stored there.

  30.        Timers decrement from it_value to zero, generate a signal, and reset to it_interval. A timer which is set to zero (it_value is zero or the
  31.        timer expires and it_interval is zero) stops.

  32.        Both tv_sec and tv_usec are significant in determining the duration of a timer.

  33.        Timers will never expire before the requested time, but may expire some (short) time afterward, which depends on the system timer resolu‐
  34.        tion and on the system load; see time(7). (But see BUGS below.) Upon expiration, a signal will be generated and the timer reset. If the
  35.        timer expires while the process is active (always true for ITIMER_VIRTUAL) the signal will be delivered immediately when generated. Other‐
  36.        wise the delivery will be offset by a small time dependent on the system loading.

  37. RETURN VALUE
  38.        On success, zero is returned. On error, -1 is returned, and errno is set appropriately.

  39. ERRORS
  40.        EFAULT new_value, old_value, or curr_value is not valid a pointer.

  41.        EINVAL which is not one of ITIMER_REAL, ITIMER_VIRTUAL, or ITIMER_PROF; or (since Linux 2.6.22) one of the tv_usec fields in the structure
  42.               pointed to by new_value contains a value outside the range 0 to 999999.
对于其配置的两个参数:
1. it_value表示配置该定时器后,经过这么长时间后,定时器会发出 sigalrm信号
2. it_interval表示在 it_value时间后,后续每隔 it_interval时间,定时器都会发出 sigalrm信号

自然,如果你仅仅需要触发一次,单独配置 it_value参数就完全可以实现

如果后续需要定时触发的话,则该两个参数都是需要进行配置才行

现在给出一段实现的代码,该实现参考网络资料

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>

  4. #include <signal.h>

  5. #include <sys/time.h>


  6. void sigHandler()
  7. {
  8.     static int iCnt = 0;
  9.     printf("The %d timer, Log here!!\n", iCnt++);
  10. }

  11. int
  12. main()
  13. {
  14.     struct itimerval tv, otv;

  15.     signal(SIGALRM, sigHandler);

  16.     tv.it_value.tv_sec = 2;
  17.     tv.it_value.tv_usec = 5 * 1000L;

  18.     tv.it_interval.tv_sec = 5;
  19.     tv.it_interval.tv_usec = 2 * 1000L;

  20.     if(setitimer(ITIMER_REAL, &tv, &otv) != 0)
  21.     {
  22.         printf("Error to settimer!!\n");
  23.     }

  24.     while(1)
  25.     {
  26.         sleep(1);
  27.         getitimer(ITIMER_REAL, &otv);
  28.         printf("otv: it_value.tv_sec: %lu, it_value.tv_usec: %lu, it_interval.tv_sec: %lu, it_interval.tv_usec: %lu\n",
  29.                 otv.it_value.tv_sec, otv.it_value.tv_usec, otv.it_interval.tv_sec, otv.it_interval.tv_usec);
  30.     }
  31. }

以上实现中
1. 由于 while中的 sleep(1),每隔一秒会打印有关 otv的信息
2. 在刚开始,2sec5msec后,会发送一个 sigalrm信号,打印 sigHandler中的 log信息
3. 后续,每隔 5sec2msec,会发送一个 sigalrm信号,打印 sigHandler中的 log信息

有以下两点需要注意:
1.  tv_usec中设置的是 microsecond,是微妙,usec。而不是毫秒 millisecond, msec。之前我一直把microsecond当成是毫秒
2. sleep函数,在设置的时间后或者收到一个不可忽略的信号后,会苏醒。

所以对于该例子中,如果sleep为 10sec或者任何大于6的值,后续 setitimer的 sigalrm信号都会把 sleep给唤醒




------------------------------------参考信息---------------------------------------------------
Linux 下setitimer函数的使用
linux上定时函数 setitimer 的使用介绍
上一篇:wireless 参数三 之 WMF
下一篇:【内核】进程切换 switch_to 与 __switch_to