在网上查看到一份关于贪吃蛇的实现代码,其中使用到 setitimer函数来触发屏幕的刷新打印
之前对该函数不甚了解,因此顺便学习下
首先是关于其的man资料。说实话我没有太看懂其使用,至少是对于 it_interval参数作用不了解
-
NAME
-
getitimer, setitimer - get or set value of an interval timer
-
-
SYNOPSIS
-
#include <sys/time.h>
-
-
int getitimer(int which, struct itimerval *curr_value);
-
int setitimer(int which, const struct itimerval *new_value,
-
struct itimerval *old_value);
-
-
DESCRIPTION
-
The system provides each process with three interval timers, each decrementing in a distinct time domain. When any timer expires, a signal
-
is sent to the process, and the timer (potentially) restarts.
-
-
ITIMER_REAL decrements in real time, and delivers SIGALRM upon expiration.
-
-
ITIMER_VIRTUAL decrements only when the process is executing, and delivers SIGVTALRM upon expiration.
-
-
ITIMER_PROF decrements both when the process executes and when the system is executing on behalf of the process. Coupled with
-
ITIMER_VIRTUAL, this timer is usually used to profile the time spent by the application in user and kernel space. SIGPROF
-
is delivered upon expiration.
-
-
Timer values are defined by the following structures:
-
-
struct itimerval {
-
struct timeval it_interval; /* next value */
-
struct timeval it_value; /* current value */
-
};
-
-
struct timeval {
-
time_t tv_sec; /* seconds */
-
suseconds_t tv_usec; /* microseconds */
-
};
-
-
The function getitimer() fills the structure pointed to by curr_value with the current setting for the timer specified by which (one of
-
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
-
timer is disabled. Similarly, it_interval is set to the reset value.
-
-
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
-
stored there.
-
-
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
-
timer expires and it_interval is zero) stops.
-
-
Both tv_sec and tv_usec are significant in determining the duration of a timer.
-
-
Timers will never expire before the requested time, but may expire some (short) time afterward, which depends on the system timer resolu‐
-
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
-
timer expires while the process is active (always true for ITIMER_VIRTUAL) the signal will be delivered immediately when generated. Other‐
-
wise the delivery will be offset by a small time dependent on the system loading.
-
-
RETURN VALUE
-
On success, zero is returned. On error, -1 is returned, and errno is set appropriately.
-
-
ERRORS
-
EFAULT new_value, old_value, or curr_value is not valid a pointer.
-
-
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
-
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参数就完全可以实现
如果后续需要定时触发的话,则该两个参数都是需要进行配置才行
现在给出一段实现的代码,该实现参考网络资料
-
#include <stdio.h>
-
#include <string.h>
-
#include <stdlib.h>
-
-
#include <signal.h>
-
-
#include <sys/time.h>
-
-
-
void sigHandler()
-
{
-
static int iCnt = 0;
-
printf("The %d timer, Log here!!\n", iCnt++);
-
}
-
-
int
-
main()
-
{
-
struct itimerval tv, otv;
-
-
signal(SIGALRM, sigHandler);
-
-
tv.it_value.tv_sec = 2;
-
tv.it_value.tv_usec = 5 * 1000L;
-
-
tv.it_interval.tv_sec = 5;
-
tv.it_interval.tv_usec = 2 * 1000L;
-
-
if(setitimer(ITIMER_REAL, &tv, &otv) != 0)
-
{
-
printf("Error to settimer!!\n");
-
}
-
-
while(1)
-
{
-
sleep(1);
-
getitimer(ITIMER_REAL, &otv);
-
printf("otv: it_value.tv_sec: %lu, it_value.tv_usec: %lu, it_interval.tv_sec: %lu, it_interval.tv_usec: %lu\n",
-
otv.it_value.tv_sec, otv.it_value.tv_usec, otv.it_interval.tv_sec, otv.it_interval.tv_usec);
-
}
-
}
以上实现中
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 的使用介绍
阅读(3332) | 评论(0) | 转发(0) |