setitimer函数
在编程的时候,很多时候会用到定时器,定时检测某个状态是否发生变化并进行处理。这时候,就会用到setitimer函数了。
1. 要使用setitimer函数,要包含头文件:#include
2. 该函数的原型是:int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value);
3. man setitimer
NAME
getitimer, setitimer - get or set value of an interval timer
SYNOPSIS
#include
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 {
long tv_sec; /* seconds */
long 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_VIR-
TUAL, 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 afterwards, which depends on the system timer resolution 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. Otherwise 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.
CONFORMING TO
POSIX.1-2001, SVr4, 4.4BSD (this call first appeared in 4.2BSD). POSIX.1-2008 marks getitimer() and setitimer() obsolete, recommending the use of the POSIX timers
API (timer_gettime(2), timer_settime(2), etc.) instead.
NOTES
A child created via fork(2) does not inherit its parent’s interval timers. Interval timers are preserved across an execve(2).
POSIX.1 leaves the interaction between setitimer() and the three interfaces alarm(2), sleep(3), and usleep(3) unspecified.
其中it_value表示设置定时器后间隔多久开始执行定时任务,而it_interval表示两次定时任务之间的时间间隔。
示例:
#include
#include
#include
#include
#include
void sigFunc()
{
static int iCnt = 0;
printf("The %d Times: Hello world\n", iCnt++);
}
int main(void)
{
struct itimerval tv, otv;
struct sigaction sa;
memset(&sa, 0, sizeof(struct sigaction));
sa.sa_handler = sigFunc;
sigemptyset(&sa.sa_mask);
if (sigaction(SIGALRM, &sa, NULL) == -1) {
printf("sigaction(SIGALRM) failed");
return -1;
}
//how long to run the first time
tv.it_value.tv_sec = 10;
tv.it_value.tv_usec = 0;
//after the first time, how long to run next time
tv.it_interval.tv_sec = 1;
tv.it_interval.tv_usec = 0;
if (setitimer(ITIMER_REAL, &tv, &otv) != 0)
printf("setitimer err %d\n", errno);
while(1)
{
sleep(1);
printf("otv: %d, %d, %d, %d\n", otv.it_value.tv_sec, otv.it_value.tv_usec, otv.it_interval.tv_sec, otv.it_interval.tv_sec);
}
}
运行结果:
otv: 0, 0, 0, 0
otv: 0, 0, 0, 0
otv: 0, 0, 0, 0
otv: 0, 0, 0, 0
otv: 0, 0, 0, 0
otv: 0, 0, 0, 0
otv: 0, 0, 0, 0
otv: 0, 0, 0, 0
otv: 0, 0, 0, 0
The 0 Times: Hello world
otv: 0, 0, 0, 0
The 1 Times: Hello world
otv: 0, 0, 0, 0
The 2 Times: Hello world
otv: 0, 0, 0, 0
说明:
it_value.tv_sec = 10,表示10秒后开始执行定时任务
it_interval.tv_sec = 1,表示间隔1秒执行定时任务
计数器超时后,发送SIGALRM信号到进程,之后计时器重启动。
函数 sigaction( int signum,const struct sigaction *act ,struct sigaction *oldact )会依参数signum指定的信号编号来设置该信号的处理函数,因为定时器发送了SIGALRM信号,因此进程接收到该信号后,执行回调函数sigFunc().