Linux下的定時器:alarm()與setitimer()

來源:互聯網
上載者:User

Linux下的定時器有兩種,以下分別介紹:

1、alarm
如果不要求很精確的話,用alarm()和signal()就夠了
unsigned int alarm(unsigned int seconds)

函數說明: alarm()用來設定訊號SIGALRM在經過參數seconds指定的秒數後傳送給目前的進程。如果參數seconds為0,則之前設定的鬧鐘會被取消,並將剩下的時間返回。
傳回值: 返回之前鬧鐘的剩餘秒數,如果之前未設鬧鐘則返回0。

alarm()執行後,進程將繼續執行,在後期(alarm以後)的執行過程中將會在seconds秒後收到訊號SIGALRM並執行其處理函數。

#include
#include
#include

void sigalrm_fn(int sig)
{
printf("alarm!/n");
alarm(2);
return;
}

int main(void)
{
signal(SIGALRM, sigalrm_fn);
alarm(1);
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
#include
#include
#include
#include
#include

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; //(1)
sec = 5;
printf("process id is %d/n", 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); //(2)
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(;;)
;
}

(1) struct itimerval

struct itimerval {
struct timeval it_interval; /* timer interval */
struct timeval it_value; /* current value */
};

itimerval: i --> interval
val --> value

itimerval結構中的it_value是減少的時間,當這個值為0的時候就發出相應的訊號了. 然後再將it_value設定為it_interval值.

(2) setitimer()
setitimer()為其所在進程設定一個定時器,如果itimerval.it_interval不為0(it_interval的兩個域都不為0),則該定時器將持續有效(每隔一段時間就會發送一個訊號)

注意:Linux訊號機制基本上是從Unix系統中繼承過來的。早期Unix系統中的訊號機制比較簡單和原始,後來在實踐中暴露出一些問題,因此,
把那些建立在早期機制上的訊號叫做"不可靠訊號",訊號值小於SIGRTMIN(SIGRTMIN=32,SIGRTMAX=63)的訊號都是不可靠信
號。這就是"不可靠訊號"的來源。它的主要問題是:進程每次處理訊號後,就將對訊號的響應設定為預設動作。在某些情況下,將導致對訊號的錯誤處理;因此,
使用者如果不希望這樣的操作,那麼就要在訊號處理函數結尾再一次調用signal(),重新安裝該訊號。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.