Linux下定時器使用

來源:互聯網
上載者:User
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(),重新安裝該訊號。 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.