linux下如何實現秒以下精確定時與休眠
linux中提供的休眠函式是sleep和alarm,但是他們僅僅提供以秒為單位的休眠,這中休眠有些程序顯然太長了,那麼怎樣才能使程序以更小的時間解析度休眠呢?
第一種方法是使用定時器,linux提供的定時器函式是:
int setitimer(int which, const struct itimerval *value, struct
itimerval *ovalue);
which指定那種定時器。linux提供3種定時器:
timer_real:
準確定時器,超時會發出sigalrm訊號;
timer_virtual: 虛擬定時器,只記程序時間,所以會根據程序執行時間而變化,不能實現準確定時,超時發出sigvtalrm訊號;
timer_prof: 梗概計時器,它會根據程序時間和系統時間而變化,不能實現準確定時,超時發出sigprof訊號;
在程序中應該捕捉所設定時器會發出的訊號,因為程序收到定時器超時發出的訊號後,預設動作是終止。
struct itimerval ;struct timeval ;
it_interval指定間隔時間,it_value指定初始定時時間。如果只指定it_value,就是實現一次定時;如果同時指定it_interval,則超時後,系統會重新初始化it_value為it_interval,實現重複定時;兩者都清零,則會清除定時器。
tv_sec提供秒級精度,tv_usec提供微秒級精度,以值大的為先,注意1s = 1000000ms。
ovalue用來儲存先前的值,常設為null。
如果是以setitimer提供的定時器來休眠,只需阻塞等待定時器訊號就可以了。
第二種方法是使用select來提供精確定時和休眠:
int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,struct timeval *timeout);
n指監視的檔案描述符範圍,通常設為所要select的fd+1,readfds,writefds和exceptfds分別是讀,寫和異常檔案描述符集,timeout為超時時間。
可能用到的關於檔案描述符集操作的巨集有:
fd_clr(int fd, fd_set *set); 清除fd我們此時用不到這些巨集,因為我們並不關心檔案描述符的狀態,我們關心的是select超時。所以我們需要把readfds,writefds和exceptfds都設為null,只指定timeout時間就行了。至於n我們可以不關心,所以你可以把它設為任何非負值。實現**如下:fd_isset(int fd, fd_set *set); 測試fd是否設定
fd_set(int fd, fd_set *set); 設定fd
fd_zero(fd_set *set); 清空描述符集
int mssleep(long ms)
結語:
setitimer和select都能實現程序的精確休眠,本文分別對他們進行了簡單介紹,並給出了乙個簡單的給予select的實現。我不推薦使用setitimer,因為一者linux系統提供的timer有限(每個程序至多能設3個不同型別的timer),再者ssetitimer實現起來沒有select簡單。
Linux下定時器的使用及實現秒以下精確定時與休眠
linux下定時器的使用 alarm setitimer 1 alarm 如果不要求很精確的話,用alarm 和signal 就夠了 unsigned int alarm unsigned int seconds 函式說明 alarm 用來設定訊號sigalrm在經過引數seconds指定的秒數後傳...
Linux下精確計時
1.低精度計時 1.1sleep 和 usleep sleep int x 系統呼叫,讓程序等待x秒鐘。其精度以秒為單位的。usleep int x 系統呼叫,讓程序等待x 納秒,但實際其精度一般是10ms,再低的達不到。這兩個函式的優點是簡單,缺點程序被阻塞。1.2alarm鬧鐘 alarm也稱為...
用rdtsc實現linux下的精確計時
在linux開發版最長問到的問題之一就是在linux下如何得到更精確的計時。其實有很多辦法,比如以前就有人用select。不過現在有更精確的實時時鐘可以用,這就是用clock process cputime id做引數通過timer create來建立timer。通過clock getres可以得到...