在linux下實現精度較高的定時功能,需要用到setitimer 和 getitimer函式。
函式原型:
#include <sys/time.h> int getitimer(int which, struct itimerval *curr_value); int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value);
· 函式getitimer()把指定的定時器型別( ITIMER_REAL, ITIMER_VIRTUAL, 或 ITIMER_PROF中的一個)寫入curr_value指向的結構。
it_value設定為定時器剩餘時間(若定時器關閉則為0)。類似的,it_interval設定為復位時間。
分析形參:
1. int which
struct itimerval { struct timeval it_interval;//next value struct timeval it_value;//current value };
timeval也是一個資料型別:
struct timeval { long tv_sec; long tv_usec; };
it_interval指定間隔時間,it_value指定初始定時時間。如果只指定it_value,就是實現一次定時;如果同時指定 it_interval,則超時後,系統會重新初始化it_value為it_interval,實現重複定時;兩者都清零,則會清除定時器。tv_sec提供秒級精度,tv_usec提供微秒級精度,以值大的為先。
3. struct itimerval *ovalue
ovalue用來儲存先前的值,通常設定為NULL。
每次定時迴圈結束會產生中斷,通常會用到signal函式捕捉處理,原型為:
#include<signal.h> void (* signal(int sig, void (*func) (int)) ) (int);
signal()是一個系統呼叫,常用來設定某個訊號(sig)的處理方法(func):
訊號型別(sig)(1) 與程式終止相關的訊號。當程式退出,或者子程式終止時,發出這類訊號。
(2) 與程式例外事件相關的訊號。如程式越界,或企圖寫一個只讀的記憶體區域(如程式正文區),或執行一個特權指令及其他各種硬體錯誤。
(3) 與在系統呼叫期間遇到不可恢復條件相關的訊號。如執行系統呼叫exec時,原有資源已經釋放,而目前系統資源又已經耗盡。
(4) 與執行系統呼叫時遇到非預測錯誤條件相關的訊號。如執行一個並不存在的系統呼叫。
(5) 在使用者態下的程式發出的訊號。如程式呼叫系統呼叫kill向其他程式傳送訊號。
(6) 與終端互動相關的訊號。如使用者關閉一個終端,或按下break鍵等情況。
下列巨集常量表示式指定了標準的訊號值:
Marcro | Signal |
SIGABRT | 異常終止,如呼叫abort(). |
SIGFPE | 如除0或操作結果溢位(不一定是浮點操作). |
SIGILL | 非法指令或無效的函式映象,通常由於程式碼錯誤或執行資料引起. |
SIGINT | 互動式中斷訊號,通常由使用者產生. |
SIGSEGV | 段衝突.訪問非法儲存空間時產生. |
SIGTERM | 發給本程式的中止訊號. |
#include<stdio.h> #include<sys/time.h> #include<signal.h> void response(void); int main() { struct itimerval my_timer; long n_sec, n_usec; my_timer.it_interval.tv_sec = 0; my_timer.it_interval.tv_usec = 300*1000;//300ms my_timer.it_value.tv_sec = 2; //2s my_timer.it_value.tv_usec = 0; setitimer(ITIMER_REAL, &my_timer, NULL); signal(SIGALRM,(__sighandler_t)&response); while(1) ; return 0; } void response(void) { printf("Receive signal!!\n"); }
上述程式碼片段將定時器初始值設為2s,迴圈值為300ms,則當setitimer函式執行以後2s產生SIGALRM中斷,由signal函式指定中斷處理函式為response();
2s之後,每隔300ms產生一次SIGALRM中斷。