2010-01-18 39 views
2

任何人都可以說明使用的GNU C的SetTimer或報警功能的程序,具有一定的程序示例,好嗎?需要一個說明在GNU C使用的SetTimer和報警功能

我有一個程序,連續地處理某些數據,以及我需要設置一個定時器/報警即熄滅每t秒,響應於其中,我需要經處理的數據存儲到文件中。這個文件寫入必須是異步的<,即數據處理和文件寫入不能等待對方>。我通過GNU C庫頁去了,但我不明白多少..

[編輯]

我得到了這個程序:

#include <stdio.h> 
#include <signal.h> 
#include <sys/time.h> 

#define INTERVAL 1 

int howmany = 0; 

void alarm_wakeup (int i) 
{ 
    struct itimerval tout_val; 

    signal(SIGALRM,alarm_wakeup); 

    howmany += INTERVAL; 

    printf("\n%d sec up partner, Wakeup!!!\n",howmany); 
    tout_val.it_interval.tv_sec = 0; 
    tout_val.it_interval.tv_usec = 0; 
    tout_val.it_value.tv_sec = INTERVAL; /* 10 seconds timer */ 
    tout_val.it_value.tv_usec = 0; 

    setitimer(ITIMER_REAL, &tout_val,0); 

} 

void exit_func (int i) 
{ 
    signal(SIGINT,exit_func); 
    printf("\nBye Bye!!!\n"); 
    exit(0); 
} 

int main() 
{ 
    struct itimerval tout_val; 

    tout_val.it_interval.tv_sec = 0; 
    tout_val.it_interval.tv_usec = 0; 
    tout_val.it_value.tv_sec = INTERVAL; /* 10 seconds timer */ 
    tout_val.it_value.tv_usec = 0; 
    setitimer(ITIMER_REAL, &tout_val,0); 

    signal(SIGALRM,alarm_wakeup); /* set the Alarm signal capture */ 
    signal(SIGINT,exit_func); 

    while (1) 
    { 
    //printf("!"); 
    } 

    return 0; 

} 

但是好像雖然我不能做任何事情定時器在.. 我應該修改哪些以適合我的需求? Pl建議..

回答

8

這是here的一個例子,它使用setitimer()定期呼叫DoStuff()

這裏的關鍵在於調用setitimer()會導致操作系統安排SIGALRM在指定時間過後發送到您的進程,並且由程序處理該信號。您可以通過註冊信號類型的信號處理函數來處理信號(在這種情況下爲DoStufF()),之後OS在計時器到期時知道調用該函數。

您可以閱讀setitimer()man page來弄清楚參數是什麼以及如何取消計時器。

注意:如果您希望計時器只觸發一次,您必須撥打alarm()ualarm()而不是setitimer()

/* 
* setitimer.c - simple use of the interval timer 
*/ 

#include <sys/time.h>  /* for setitimer */ 
#include <unistd.h>  /* for pause */ 
#include <signal.h>  /* for signal */ 

#define INTERVAL 500  /* number of milliseconds to go off */ 

/* function prototype */ 
void DoStuff(void); 

int main(int argc, char *argv[]) { 

    struct itimerval it_val; /* for setting itimer */ 

    /* Upon SIGALRM, call DoStuff(). 
    * Set interval timer. We want frequency in ms, 
    * but the setitimer call needs seconds and useconds. */ 
    if (signal(SIGALRM, (void (*)(int)) DoStuff) == SIG_ERR) { 
    perror("Unable to catch SIGALRM"); 
    exit(1); 
    } 
    it_val.it_value.tv_sec =  INTERVAL/1000; 
    it_val.it_value.tv_usec = (INTERVAL*1000) % 1000000; 
    it_val.it_interval = it_val.it_value; 
    if (setitimer(ITIMER_REAL, &it_val, NULL) == -1) { 
    perror("error calling setitimer()"); 
    exit(1); 
    } 

    while (1) 
    pause(); 

} 

/* 
* DoStuff 
*/ 
void DoStuff(void) { 

    printf("Timer went off.\n"); 

} 
+0

感謝,如果我想這整個報警運行作爲背景如何修改這一點,同時我可以處理一些數據..和正時警報響起時,我寫的東西到一個文件中。 。正如我之前所說,這兩個這些即處理和文件寫入是異步的.. – trinity 2010-01-18 13:53:42

+0

非常感謝,我做了一些改變這個程序,我幾乎得到了我想要的..(我現在要去嘗試它我目前正在使用的數據包捕獲項目) – trinity 2010-01-18 15:41:16

+0

在您的代碼中,您最終將在main()中旋轉,因此您可以在那裏處理空循環而不是空循環。每當你得到SIGALRM,你的代碼都會暫停,信號處理程序得到控制。一旦信號處理程序完成,您的代碼將再次繼續。因此,您可以使用信號處理程序設置一個標誌,指示您應該寫入文件,然後在處理循環中檢查該標誌。如果已設置,您將寫入文件並將標誌重置爲false。但是這種解決方案不是異步的,即報警/信號處理器只會設置一個標誌而不是寫入文件。 – liwp 2010-01-18 22:18:41