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;
		}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章