Linux下的定時器有兩種,以下分別介紹:
1、alarm
如果不要求很精確的話,用 alarm() 和 signal() 就夠了
unsigned int alarm(unsigned int seconds)
專門為SIGALRM訊號而設,在指定的時間seconds秒後,將向進程本身發送SIGALRM訊號,又稱為鬧鐘時間。進程調用alarm後,任何以前的alarm()調用都將無效。如果參數seconds為零,那麼進程內將不再包含任何鬧鐘時間。如果調用alarm()前,進程中已經設定了鬧鐘時間,則返回上一個鬧鐘時間的剩餘時間,否則返回0。
樣本:
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void sigalrm_fn(int sig)
{
/* Do something */
printf("alarm!/n");
alarm(2);
return;
}
int main(void)
{
signal(SIGALRM, sigalrm_fn);
alarm(2);
/* Do someting */
while(1) pause();
}
2、setitimer
int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue));
setitimer()比alarm功能強大,支援3種類型的定時器:
ITIMER_REAL : 以系統真實的時間來計算,它送出SIGALRM訊號。
ITIMER_VIRTUAL : 以該行程真正有執行的時間來計算,它送出SIGVTALRM訊號。
ITIMER_PROF : 以行程真正有執行及在核心中所費的時間來計算,它送出SIGPROF訊號。
Setitimer()第一個參數which指定定時器類型(上面三種之一);第二個參數是結構itimerval的一個執行個體;第三個參數可不做處理。
Setitimer()調用成功返回0,否則返回-1。
下面是關於setitimer調用的一個簡單示範,在該例子中,每隔一秒發出一個SIGALRM,每隔0.5秒發出一個SIGVTALRM訊號::
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
int sec;
void sigroutine(int signo){
switch (signo){
case SIGALRM:
printf("Catch a signal -- SIGALRM /n");
signal(SIGALRM, sigroutine);
break;
case SIGVTALRM:
printf("Catch a signal -- SIGVTALRM /n");
signal(SIGVTALRM, sigroutine);
break;
}
return;
}
int main()
{
struct itimerval value, ovalue, value2;
sec = 5;
printf("process id is %d ", getpid());
signal(SIGALRM, sigroutine);
signal(SIGVTALRM, sigroutine);
value.it_value.tv_sec = 1;
value.it_value.tv_usec = 0;
value.it_interval.tv_sec = 1;
value.it_interval.tv_usec = 0;
setitimer(ITIMER_REAL, &value, &ovalue);
value2.it_value.tv_sec = 0;
value2.it_value.tv_usec = 500000;
value2.it_interval.tv_sec = 0;
value2.it_interval.tv_usec = 500000;
setitimer(ITIMER_VIRTUAL, &value2, &ovalue);
for(;;)
;
}
該例子的螢幕拷貝如下:
localhost:~$ ./timer_test
process id is 579
Catch a signal – SIGVTALRM
Catch a signal – SIGALRM
Catch a signal – SIGVTALRM
Catch a signal – SIGVTALRM
Catch a signal – SIGALRM
Catch a signal –GVTALRM
注意:Linux訊號機制基本上是從Unix系統中繼承過來的。早期Unix系統中的訊號機制比較簡單和原始,後來在實踐中暴露出一些問題,因此,把那些建立在早期機制上的訊號叫做"不可靠訊號",訊號值小於SIGRTMIN(Red hat 7.2中,SIGRTMIN=32,SIGRTMAX=63)的訊號都是不可靠訊號。這就是"不可靠訊號"的來源。它的主要問題是:進程每次處理訊號後,就將對訊號的響應設定為預設動作。在某些情況下,將導致對訊號的錯誤處理;因此,使用者如果不希望這樣的操作,那麼就要在訊號處理函數結尾再一次調用signal(),重新安裝該訊號。