参考资料 linux函数setitimer 传送门
(北京邮电大学计算机科学与技术系操作系统实验——2.2内核定时器)
linux操作系统下
记录一个进程运行时所占用的real time, cpu time,user time ,kernel time
参考代码及其精讲
#include <sys/time.h>
#include <stdio.h>
#include <signal.h>
static void sighandle(int); //自定义信号处理函数
static long realsecond = 0;
static long vtsecond = 0;
static long profsecond = 0;
static struct itimerval realt,virtt,proft;
int main(){
struct itimerval v; //创建变量v
int i,j;
long moresec,moremsec,t1,t2; //more_sec more_mesc,t1,t2
//捕捉信号SIGALRM,使用函数sighandle对信号进行处理
//signal函数中第一个参数位要处理的信号,第二个参数位要处理的措施,使用相应函数来操作
signal(SIGALRM,sighandle); //信号 ALRM
signal(SIGVTALRM,sighandle); // VTALRM
signal(SIGPROF,sighandle); //PROF
v.it_interval.tv_sec = 10; //定时器启动后,每隔10s将执行相应的函数
v.it_interval.tv_usec = 0;
v.it_value.tv_sec = 10; //10s后将启动定时器,延迟时间
v.it_value.tv_usec = 0;
//设置定时器,第一个参数表示对什么计时,第二个参数v来指示延迟时间和间隔时间,第三个参数一般取null,不用管
setitimer(ITIMER_REAL,&v,NULL); // ITIMER_REAL:以系统真实的时间来计算,它送出SIGALRM信号。
setitimer(ITIMER_VIRTUAL,&v,NULL); // ITIMER_VIRTUAL:以该进程在用户态下花费的时间来计算,它送出SIGVTALRM信号。
setitimer(ITIMER_PROF,&v,NULL); // ITIMER_PROF:以该进程在用户态下和内核态下所费的时间来计算,它送出SIGPROF信号。
//这里放了一个函数体,程序执行需要耗费时间
for(j= 0;j<1000;j++){
for(i= 0;i<500;i++)
{
printf("********\r");
fflush(stdout);
}
}
//用计时器的当前值写value指向的结构体
getitimer(ITIMER_PROF,&proft);
getitimer(ITIMER_REAL,&realt);
getitimer(ITIMER_VIRTUAL,&virtt);
printf("\n");
/*
settimer工作机制是,先对it_value倒计时,当it_value为零时触发信号,然后重置为it_interval,继续对it_value倒计时,一直这样循环下去。
基于此机制,setitimer既可以用来延时执行,也可定时执行。
*/
/*这里realt.it_value_tv_sec的值为0-10,并且循环执行,从10开始,每秒递减,当为0的时候触发sighandle()事件,同时初始化为10。*/
moresec = 10 - realt.it_value.tv_sec; //realt.it_value.tv_sec值逐渐递减,由10s开始递减
moremsec = (1000000 - realt.it_value.tv_usec)/1000; // 转换成ms
printf("realtime = %ld sec, %ld msec\n",realsecond+moresec,moremsec);
moresec = 10 - proft.it_value.tv_sec;
moremsec = (1000000 - proft.it_value.tv_usec)/1000;
printf("cputime = %ld sec, %ld msec\n",profsecond+moresec,moremsec);
moresec = 10 - virtt.it_value.tv_sec;
moremsec = (1000000 - virtt.it_value.tv_usec)/1000;
printf("usertime = %ld sec, %ld msec\n",vtsecond+moresec,moremsec);
/*
t1=用户态执行时间
t2=用户态+内核执行时间
t2-t1 = 内核执行时间 kernel time
*/
t1 = (10 - proft.it_value.tv_sec)*1000 + (1000000 - proft.it_value.tv_usec)/1000 + profsecond*10000;
t2 = (10 - virtt.it_value.tv_sec)*1000 + (1000000 - virtt.it_value.tv_usec)/1000 + vtsecond*10000;
moresec = (t1 - t2)/1000;
moremsec = (t1 - t2) % 1000;
printf("kerneltime = %ld sec, %ld msec\n",moresec,moremsec);
fflush(stdout);
}
static void sighandle(int s)
{
switch(s){
case SIGALRM: realsecond+=10;break;
case SIGVTALRM: vtsecond+=10;break;
case SIGPROF: profsecond+=10;break;
default :break;
}
}