1 setitimer函数
该函数可以代替上一篇文章的alarm定时器函数,作用都是在一定时间后发送相应的信号给进程。
int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value);
/*
功能:设置定时器(闹钟)。 可代替alarm函数。精度微秒us,可以实现周期定时。
成功:0;失败:-1,设置errno。
参数1:which:指定定时方式。
① 自然定时:默认发送ITIMER_REAL → 即编号为14的SIGLARM信号。 计算自然时间
② 虚拟空间计时(用户空间):默认发送ITIMER_VIRTUAL → 即编号为26的SIGVTALRM 只计算进程占用cpu的时间
③ 运行时计时(用户+内核):默认发送ITIMER_PROF → 即编号为27的SIGPROF 计算占用cpu及执行系统调用的时间
参数2:new_value是定时秒数。
参数3:old_value是传出参数,表示设置上次定时的剩余时间。
struct itimerval {
struct timeval it_interval;/*next value,即下一次触发定时信号的时间间隔(周期定时)。为0时不进行周期任务。*/
struct timeval it_value;/*current value,首次定时触发信号的时长。当这两个参数都设置为0,与alarm取消定时器的清0操作一样。*/
};
struct timeval{
time_t tv_sec; /*s*/
suseconds_t tv_usec;/*ms*/
};
这里我们简单的举个关于new_value传参的例子。(old_value是传出参数,不需要传参)
itimerval new_value;
new_value.it_value.tv_sec = 2;
new_value.it_value.tv_usec = 0;
//上面代表程序启动后首次触发定时发送信号是2秒后
new_value.it_interval.tv_sec = 5;
new_value.it_interval.tv_usec = 0;
/*
而这里的5代表首次触发即2秒后,下一次触发时间为5s,并且会自动发送定时信号,
无需再次调用setitimer,这就是周期定时。即第二次发送定时时间为第7秒,第三次为第12秒...一直往下
若你不想循环周期定时,将其置为0即可。一般我们不使用到tv_usec微秒,只需要用tv_sec这一个成员即可。
*/
*/
2 setitimer函数案例
使用setitimer函数实现alarm函数,重复计算机1秒数数程序。
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
unsigned int my_alarm(unsigned int sec){
struct itimerval it, oldit;
int ret;
it.it_value.tv_sec = sec;
it.it_value.tv_usec = 0;
it.it_interval.tv_sec = 0;
it.it_interval.tv_usec = 0;
ret = setitimer(ITIMER_REAL, &it, &oldit);
if (ret == -1) {
perror("setitimer");
exit(1);
}
return oldit.it_value.tv_sec;
}
int main(void){
int i;
/*使用setitimer自定义实现alarm函数*/
my_alarm(1); //alarm(sec);
for(i = 0; ; i++)
printf("%d\n", i);
return 0;
}