2013-11-05 81 views
0

我需要能夠同時啓動多個定時器,並明確知道定時器是否已停止或仍在運行。啓動多個定時器並知道哪一個已經結束C

#define RESEND_TIMEOUT 5 

void timer_set_timeout(timer_t * timer, uint32_t timeout); 
void timer_start(timer_t * timer); 
bool timer_complete(timer_t * timer); 
void signal_handler(int sig, siginfo_t *si, void *uc); 

int main() { 
    timer_t resend_timer; 
    printf("starting timer\n"); 
    timer_start(&resend_timer); 
    timer_set_timeout(RESEND_TIMEOUT); 
    while(1) { 

    if (timer_complete(&resend_timer)) 
     break; 
    } 
} 

void timer_set_timeout(timer_t * timer, uint32_t timeout) 
{ 
    struct itimerspec it_val; 
    it_val.it_value.tv_sec = timeout; 
    it_val.it_value.tv_nsec = 0; 
    it_val.it_interval.tv_sec = 0; 
    it_val.it_interval.tv_nsec = 0; 
    if (timer_settime(*timer, 0, &it_val, NULL) == -1) { 
     errExit("Could not set timeout"); 
    } 
} 

void timer_start(timer_t * timer) 
{ 
    struct sigaction sa; 
    struct sigevent sev; 

    // establish signal handler 
    sa.sa_flags = SA_SIGINFO; 
    sa.sa_sigaction = signal_handler; 
    sigemptyset(&sa.sa_mask); 
    if (sigaction(SIG, &sa, NULL) == -1) 
     errExit("Failed to establish signal handler"); 

    // create timer 
    sev.sigev_notify = SIGEV_SIGNAL; 
    sev.sigev_signo = SIG; 
    sev.sigev_value.sival_ptr = timer; 

    if(timer_create(CLOCK_MONOTONIC, &sev, timer) == -1) { 
     errExit("Could not start timer"); 
    } 
} 

// return true if timer ended 
bool timer_complete(timer_t * timer) 
{ 
    if(timer_getoverrun(*timer) == 0) 
     return false; 
    else 
     return true; 
} 

void signal_handler(int sig, siginfo_t *si, void *uc) 
{ 
    printf("Timer ran out!\n"); 
    signal(sig, SIG_IGN); 
} 

信號處理程序運行5秒後,但我無法知道計時器是否已結束或不使用timer_complete。我試過了:int timer_gettime(timer_t timerid,struct itimerspec * curr_value) 但我不知道curr_value傳遞什麼。我試過聲明一個itimerspec,但它的結果與getoverrun相同。

我也試過用timer_settime的標誌TIMER_ABSTIME,但定時器由於某種原因立即失效。

回答

0

你誤解了什麼意思表示定時器正在完成。

從頭開始,計時器有2組值。一套是定時器將來關閉的時間;另一個是間隔值,用於在定時器關閉後重新加載第一個設置。如果使用第一組但是間隔值被設置爲零,那麼它根據定義是一次性定時器。如果間隔值不爲零,那麼計時器將重新加載並永久啓動,直到關閉它爲止。通過將所有值設置爲零來關閉它,使用timer_settimer

所以在你timer_complete應該是這個樣子:

// return true if timer ended 
bool timer_complete(timer_t * timer) 
{ 
    struct itimerspec its; 

    if (timer_gettime(*timer, &its) == -1) 
    { 
     perror("timer_settime"); 
     exit(1); 
    } 

    If ((its.it_value.tv_sec == 0) && 
     (its.it_value.tv_nsec == 0) && 
     (its.it_interval.tv_sec == 0) && 
     (its.it_interval.tv_nsec == 0)) 
     return true; 
    else 
     return false; 
} 

溢出是不同的動物。基本上,操作系統不會排隊定時器信號多倍,甚至實時信號,因爲可能只有太多。溢出告訴你一個定時器發生了多少次,這是可能排隊的信號,發生在你的程序收到信號之前。

+0

沒有必要測試間隔字段。 timer_settimer(3)說:「如果new_value-> it_value指定一個零值(即兩個子字段均爲零),那麼定時器將被撤防。」 – ValenceElectron

相關問題