<menu id="w8yyk"><menu id="w8yyk"></menu></menu>
  • <dd id="w8yyk"><nav id="w8yyk"></nav></dd>
    <menu id="w8yyk"></menu>
    <menu id="w8yyk"><code id="w8yyk"></code></menu>
    <menu id="w8yyk"></menu>
    <xmp id="w8yyk">
    <xmp id="w8yyk"><nav id="w8yyk"></nav>
  • 網站首頁 > 物聯資訊 > 技術分享

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

    2016-09-28 00:00:00 廣州睿豐德信息科技有限公司 閱讀
    睿豐德科技 專注RFID識別技術和條碼識別技術與管理軟件的集成項目。質量追溯系統、MES系統、金蝶與條碼系統對接、用友與條碼系統對接

    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(),重新安裝該信號。

    RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成
    最近免费观看高清韩国日本大全