使用定時器的目的無非是為了週期性的執行某一任務,或者是到了乙個指定時間去執行某乙個任務。要達到這一目的,一般有兩個常見的比較有效的方法。乙個是用linux
內部的三個定時器;另乙個是用sleep
或usleep
函式讓程序睡眠一段時間;其實,還有乙個方法,那就是用gettimeofday
、difftime
等自己來計算時間間隔,然後時間到了就執行某一任務,但是這種方法效率低,所以不常用。
如果不要求很精確的話,用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=32
,sigrtmax=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
的話,就會出現72us
和10us
經常交替出現,無法實現精確的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...