Linux下如何實現秒以下精確定時與休眠

2021-04-14 13:18:45 字數 1799 閱讀 2172

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

fd_isset(int fd, fd_set *set);  測試fd是否設定

fd_set(int fd, fd_set *set);     設定fd

fd_zero(fd_set *set);             清空描述符集

我們此時用不到這些巨集,因為我們並不關心檔案描述符的狀態,我們關心的是select超時。所以我們需要把readfds,writefds和exceptfds都設為null,只指定timeout時間就行了。至於n我們可以不關心,所以你可以把它設為任何非負值。實現**如下:

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可以得到...