使用定時器的目的無非是為了周期性的執行某一任務,或者是到了一個指定時間去執行某一個任務。要達到這一目的,一般有兩個常見的比較有效方法。一個是用linux內部的三個定時器,另一個是用sleep, usleep函數讓進程睡眠一段時間,其實,還有一個方法,那就是用gettimeofday, difftime等自己來計算時間間隔,然後時間到了就執行某一任務,但是這種方法效率低,所以不常用。
首先來看看linux作業系統為每一個進程提供的3個內部計時器。
ITIMER_REAL: 給一個指定的時間間隔,按照實際的時間來減少這個計數,當時間間隔為0的時候發出SIGALRM訊號
ITIMER_VIRTUAL: 給定一個時間間隔,當進程執行的時候才減少計數,時間間隔為0的時候發出SIGVTALRM訊號
ITIMER_PROF: 給定一個時間間隔,當進程執行或者是系統為進程調度的時候,減少計數,時間到了,發出SIGPROF訊號,這個和ITIMER_VIRTUAL聯合,常用來計算系統核心程式的時間和使用者時間。
用到的函數有:
#include
int getitimer(int which, struct itimerval *value);
int setitimer(int which, struct itimerval*newvalue, struct itimerval* oldvalue);
strcut timeval
{
long tv_sec; /*秒*/
long tv_usec; /*微秒*/
};
struct itimerval
{
struct timeval it_interval; /*時間間隔*/
struct timeval it_value; /*目前時間計數*/
};
it_interval用來指定每隔多長時間執行任務, it_value用來儲存目前時間離執行任務還有多長時間。比如說, 你指定it_interval為2秒(微秒為0),開始的時候我們把it_value的時間也設定為2秒微秒為0),當過了一秒, it_value就減少一個為1, 再過1秒,則it_value又減少1,變為0,這個時候發出訊號告訴使用者時間到了,可以執行任務了),並且系統自動把it_value的時間重設為it_interval的值,即2秒,再重新計數。
為了協助你理解這個問題,我們來看一個例子:
#include
#include
#include
#include
#include
static char msg[] = "time is running out\n";
static int len;
// 向標準錯誤輸出資訊,告訴使用者時間到了
void prompt_info(int signo)
{
write(STDERR_FILENO, msg, len);
}
// 建立訊號處理機制
void init_sigaction(void)
{
struct sigaction tact;
/*訊號到了要執行的任務處理函數為prompt_info*/
tact.sa_handler = prompt_info;
tact.sa_flags = 0;
/*初始化訊號集*/
sigemptyset(&tact.sa_mask);
/*建立訊號處理機制*/
sigaction(SIGALRM, &tact, NULL);