五、使用setitimer(2)设置定时器
系统计时器:
系统运行一个进程的时候,进程消耗的时间包括三部分:
用户时间 进程消耗在用户态的时间
内核时间 进程消耗在内核态的时间
睡眠时间 进程消耗在等待I/O,睡眠等不被调度的时间
系统为每个进程维护三个计时器:
真实计时器 统计进程的执行时间
虚拟计时器 统计进程的用户时间
实用计时器 统计进程的用户时间和内核时间
这三个计时器除了统计功能以外,还可以按照自己的规则以定时器的方式工作向进程周期性的发送信号
利用这个功能设计一个定时器
#include <sys/time.h>
int setitimer(int which, const struct itimerval *new_value,struct itimerval *old_value);
功能:设置定时器的间隔值
参数:
which: 定时器的类型
3选1
ITIMER_REAL: 真实 SIGALRM
ITIMER_VIRTUAL:虚拟 SIGVTALRM
ITIMER_PROF: 使用 SIGPROF
new_value:指定了定时器的新值
old_value:保存了定时器的旧值
返回值:0 成功
-1 错误 errno被设置
struct itimerval {
struct timeval it_interval; /* next value */ 时间间隔
struct timeval it_value; /* current value */ 起始时间
};
struct timeval {
long tv_sec; /* seconds */ 秒级精度
long tv_usec; /* microseconds */ 微秒级精度
};
1S=1000毫秒
1毫秒=1000微秒
举例说明,编写代码实现定时器,起始时间是进程启动3秒,然后每0.5秒发送一个SIGALRM信号(timer.c)
程序:
#include <stdio.h>
#include <sys/time.h>
#include <signal.h>
void doit(int n) {
printf("recv....%d\n", n);
return;
}
int main(void) {
struct itimerval new;//定义new变量
signal(SIGALRM, doit);//更改信号处理函数
//初始化new
new.it_value.tv_sec = 3;
new.it_value.tv_usec = 0;
//设置间隔时间
new.it_interval.tv_sec = 0;
new.it_interval.tv_usec = 500000; //1s=1000000vs
//设置定时器
int s = setitimer(ITIMER_REAL,&new, NULL); //产生一个闹钟信号
if(s==-1) {
perror("setitimer");
return -1;
}
while(1);
return 0;
}
命令: tarena@ubuntu:~/day/day33$ a.out //执行之后,先3然后每隔0.5秒发一次信号
结果: recv....14
recv....14
recv....14
recv....14
recv....14
recv....14