linux下函数setitimer精讲

参考资料 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;
		}
}
发布了174 篇原创文章 · 获赞 18 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_41173604/article/details/103248618