Linux下定時的實現

來源:互聯網
上載者:User

轉載自:http://www.cnblogs.com/feisky/archive/2010/03/20/1690561.html

使用定時器的目的無非是為了周期性的執行某一任務,或者是到了一個指定時間去執行某一個任務。要達到這一目的,一般有兩個常見的比較有效方法。

一個是用linux內部的三個定時器:ITIME_REAL,ITIMER_VIRTUAL,ITIME_PROF;

另一個是用sleep, usleep函數讓進程睡眠一段時間;

其實,還有一個方法,那就是用gettimeofday(), difftime()等自己來計算時間間隔,然後時間到了就執行某一任務,但是這種方法效率低,所以不常用。

1. 系統提供的定時器

linux作業系統為每一個進程提供的3個內部計時器:

ITIMER_REAL: 給一個指定的時間間隔,按照實際的時間來減少這個計數,當時間間隔為0的時候發出SIGALRM訊號

ITIMER_VIRTUAL: 給定一個時間間隔,當進程執行的時候才減少計數,時間間隔為0的時候發出SIGVTALRM訊號

ITIMER_PROF: 給定一個時間間隔,當進程執行或者是系統為進程調度的時候,減少計數,時間到了,發出SIGPROF訊號,這個和ITIMER_VIRTUAL聯合,常用來計算系統核心程式的時間和使用者時間。

用到的函數有:

#include<sys/time.h>
 
int getitimer(intwhich,structitimerval
*value);
int setitimer(intwhich,structitimerval*newvalue,structitimerval*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秒,再重新計數。

struct sigaction
{
    void     (*sa_handler)(int);
    void     (*sa_sigaction)(int, siginfo_t *, void *);
    sigset_t   sa_mask;
    int        sa_flags;
    void     (*sa_restorer)(void);
};
其中,sa_handler是一個指標,指向訊號處理函數;

與後面兩種實現方式的主要區別:
由於定時器時系統自身提供的,所以時間到了之後,訊息也是由系統自動傳給訊息佇列的;
而後兩種由於是使用者自己實現,所以必須將進程ID和訊號ID傳送到訊息佇列(通過sigqueue()函數來實現)。

使用步驟:

1. 初始化定時器的類型和時間間隔;

2. 初始化訊號的類型和回呼函數;

3. 設定時間到了後,回呼函數執行;

樣本:

#include <stdio.h>#include <signal.h>#include <sys/time.h>#include <string.h>#include <unistd.h>//訊號回呼函數void sign_proc(int signo){    printf("time is running out\n");}//建立訊號處理機制void init_sigaction(){    struct sigaction signact;    //指定有訊號之後的回呼函數    signact.sa_handler=sign_proc;    signact.sa_flags=0;    //初始化訊號集    sigemptyset(&signact.sa_mask);    //指定訊號類型,注意與定時器類型保持一致    sigaction(SIGALRM, &signact, NULL);}//設定定時器void init_time(){    struct itimerval interval;    //初始值    interval.it_value.tv_sec=5;    interval.it_value.tv_usec=0;    //間隔時間    interval.it_interval=interval.it_value;    //設定定時器類型為:ITIMER_REAL    setitimer(ITIMER_REAL, &interval, NULL);}int main(){    init_time();    init_sigaction();    while(1);    return 0;}

說明:程式設定定時器類型為即時定時器:ITMER_REAL,每隔5秒鐘都會發送一個SIGALRM訊號,當主函數接收到了這個訊號之後,調用訊號處理函數sign_proc處理。

對於ITIMER_VIRTUAL和ITIMER_PROF的使用方法類似,當你在setitimer裡面設定的定時器為ITIMER_VIRTUAL的時候,你把sigaction裡面的SIGALRM改為SIGVTALARM, 同理,ITIMER_PROF對應SIGPROF。

2. 通過sleep以及usleep實現定時

#include <signal.h>#include <unistd.h>#include <string.h>#include <stdio.h>void show_msg(int signo){    printf("time is using up\n");}int main(){    struct sigaction signact;    union sigval tsval;    //設定訊號的回呼函數    signact.sa_handler=show_msg;    signact.sa_flags=0;    //初始化訊號集    sigemptyset(&signact.sa_mask);    sigaction(50, &signact, NULL);    while(1)    {        sleep(2);        sigqueue(getpid(), 50, tsval);    }    return 0;}

看到了吧,這個要比上面的簡單多了,而且你用秒錶測一下,時間很准,指定2秒到了就給你輸出一個字串。所以,如果你只做一般的定時,到了時間去執行一個任務,這種方法是最簡單的。

3. 通過自己計算時間差的方法來定時

#include <signal.h>#include <unistd.h>#include <string.h>#include <stdio.h>#include <time.h>void sign_proc(int signo){    printf("time is running out\n");}int main(){    struct sigaction signact;    union sigval tsval;        //設定訊號變數    signact.sa_handler=sign_proc;    signact.sa_flags=0;    sigemptyset(&signact.sa_mask);    sigaction(50, &signact, NULL);    time_t oldtime;    time(&oldtime);    while(1)    {        time_t nowtime;        time(&nowtime);                if(nowtime-oldtime>=2)        {            //將進程ID,訊號ID放到訊息機制中            sigqueue(getpid(), 50, tsval);            oldtime=nowtime;        }    }}

這種做法效率比較低,一般很少使用。

這個和上面不同之處在於,是自己手工計算時間差的,如果你想更精確的計算時間差,你可以把 time 函數換成gettimeofday,這個可以精確到微妙。

上面介紹的幾種定時方法各有千秋,在計時效率上、方法上和時間的精確度上也各有不同,採用哪種方法,就看你程式的需要。

相關文章

聯繫我們

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