參考資料 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;
}
}