Linuxc 關於Linux的應用層定時器

2021-10-07 02:02:16 字數 3297 閱讀 6176

使用定時器的目的無非是為了週期性的執行某一任務,或者是到了乙個指定時間去執行某乙個任務。要達到這一目的,一般有兩個常見的比較有效的方法。乙個是用linux內部的三個定時器;另乙個是用sleepusleep函式讓程序睡眠一段時間;其實,還有乙個方法,那就是用gettimeofdaydifftime等自己來計算時間間隔,然後時間到了就執行某一任務,但是這種方法效率低,所以不常用。

如果不要求很精確的話,用alarm()signal()就夠了

unsigned int alarm(unsigned int seconds)
專門為sigalrm訊號而設,在指定的時間seconds秒後,將向程序本身傳送sigalrm訊號,又稱為鬧鐘時間。程序呼叫alarm後,任何以前的alarm()呼叫都將無效。如果引數seconds為零,那麼程序內將不再包含任何鬧鐘時間。如果呼叫alarm()前,程序中已經設定了鬧鐘時間,則返回上乙個鬧鐘時間的剩餘時間,否則返回0

示例:

#include #include #include void sigalrm_fn(int sig)

int main(void)

int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue));

int getitimer(int which, struct itimerval *value);

strcut timeval

;struct itimerval

;

setitimer()alarm()功能強大,支援3種型別的定時器:

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

itimer_virtual:給定乙個時間間隔,當程序執行的時候才減少計數,時間間隔為0的時候發出si**talrm訊號。

itimer_prof:給定乙個時間間隔,當程序執行或者是系統為程序排程的時候,減少計數,時間到了,發出sigprof訊號。

setitimer()第乙個引數which指定定時器型別(上面三種之一);第二個引數是結構itimerval的乙個例項;第三個引數可不做處理。

下面是關於setitimer呼叫的乙個簡單示範,在該例子中,每隔一秒發出乙個sigalrm,每隔0.5秒發出乙個si**talrm訊號::

#include #include #include #include #include #include int sec;

void sigroutine(int signo)

return;

}int main()

該例子的執行結果如下:

localhost:~$ ./timer_test

process id is 579

catch a signal – si**talrm

catch a signal – sigalrm

catch a signal – si**talrm

catch a signal – si**talrm

catch a signal – sigalrm

catch a signal –**talrm

注意:linux訊號機制基本上是從unix系統中繼承過來的。早期unix系統中的訊號機制比較簡單和原始,後來在實踐中暴露出一些問題,因此,把那些建立在早期機制上的訊號叫做」不可靠訊號」,訊號值小於sigrtmin(red hat 7.2中,sigrtmin=32sigrtmax=63)的訊號都是不可靠訊號。這就是」不可靠訊號」的**。它的主要問題是:程序每次處理訊號後,就將對訊號的響應設定為預設動作。在某些情況下,將導致對訊號的錯誤處理;因此,使用者如果不希望這樣的操作,那麼就要在訊號處理函式結尾再一次呼叫signal(),重新安裝該訊號。

需要在kernel中開啟「high resolution timer support」,驅動程式中hrtimer的初始化如下:

hrtimer_init(&m_timer, clock_monotonic, hrtimer_mode_rel_pinned);

m_timer.function = vibrator_timer_func;

hrtimer_start(&m_timer, ktime_set(0, 62500), hrtimer_mode_rel_pinned);

定時函式vibrator_timer_func如下:

static enum hrtimer_restart vibrator_timer_func(struct hrtimer *timer)

其中gpio_test為輸出引腳,為了方便輸出檢視。但是用示波器檢視引腳波形時,發現雖然設定的週期為62.5us,但是輸出總是為72us左右,而且偶爾會有兩個波形靠的很近(也就是說週期突然變為10us以下)。我將週期設到40us的話,就會出現72us10us經常交替出現,無法實現精確的40us的波形,如果設定到100us時,則波形就是100us了,而且貌似沒有看到有10us以下的週期出現。

關於LINUX C庫函式 中的 fprintf

初學linux c庫,能見到它的原型如下 int fprintf file stream,const char format,查程式例時,見到如下呼叫 fprint stderr,cannot open output file.n 通常是指程式輸入或輸出的乙個連續的位元組序列,裝置 例如滑鼠 鍵盤 ...

linux下LFTP mirror的高階應用

linux下lftp mirror的高階應用 在我剛剛發現lftp的時候,我就注意到了它功能強大的mirror功能。因為它可以給 mirror 命令傳入引數,控制同步的行為 reverse 上傳到ftp上,也可以使用 r delete 如果遠端目錄下已經沒有某個檔案,而本地有,則刪除這個檔案。ign...

linux下LFTP mirror的高階應用

在我剛剛發現lftp的時候,我就注意到了它功能強大的mirror功能。因為它可以給 mirror 命令傳入引數,控制同步的行為 reverse 上傳到ftp上,也可以使用 r delete 如果遠端目錄下已經沒有某個檔案,而本地有,則刪除這個檔案。ignore time,來遮蔽時間判定,這樣mirr...