2015-07-10 50 views
5

在C++ for Linux中,我試圖做一些事情每微秒/納秒,我目前正在使用下面的nanosleep函數。它的工作原理,但是如果代碼循環數百萬次,這變得昂貴。我正在尋找一個高分辨率定時器,可以實現非常精確的定時(應用程序是音頻/視頻)。有任何想法嗎?尋找一個高分辨率的計時器

struct timespec req = {0}; 
req.tv_sec = 0; 
req.tv_nsec = 1000000000L/value; 

for(long i = 0; i < done; i++) 
{ 
    printf("Hello world");    
    nanosleep(&req, (struct timespec *)NULL); 
} 
+2

有什麼問題''? – chris

+2

如果您的CPU具有4 GHz的時鐘,則在納秒內有4個時鐘週期。即使在這樣的速度下,你也不能每秒都做很多事情。 –

+0

我們在談論什麼樣的Linux和處理器?對於非實時系統,任何高於ms精度的東西都已經相當雄心勃勃。微秒(更不用說納秒級)的準確度是你在大多數實時系統上都不會爭取的。 – MikeMB

回答

4

使用C++11

#include <chrono> 
#include <thread> 

... 

for (long i = 0; i < done; i++) { 
    std::cout << "Hello world" << std::endl;    
    std::this_thread::sleep_for(std::chrono::nanoseconds(1e9/value)); 
} 

記得用-std=c++11標誌進行編譯。

+0

我比較了兩種方法,他們似乎有非常相似的計算費用(系統調用需要很長時間)。這真的是最好的,或者可以直接從內核中使用特殊的定時器? – Josh

+0

@Josh我認爲這是最好的,可以從用戶方面完成。 – Shreevardhan

0

你可以得到getitimer(2)微秒分辨率:

http://man7.org/linux/man-pages/man2/setitimer.2.html

+0

請注意,POSIX標記['setitimer()'](http://pubs.opengroup.org/onlinepubs/9699919799/functions/setitimer.html)和 ['getitimer()'](http://pubs.opengroup .org/onlinepubs/9699919799/functions/getitimer.html)已過時,並表示首選替換函數是 ['timer_settime()'](http://pubs.opengroup.org/onlinepubs/9699919799/functions/timer_settime .html)和 ['timer_gettime()'](http://pubs.opengroup.org/onlinepubs/9699919799/functions/timer_gettime.html)。 'getitimer()'和'setitimer()'函數不會立即消失,但寫在牆上。 –

+0

OTOH,Mac OS X 10.10.4沒有'timer_settime()'或'timer_gettime()',但它確實有'getitimer()'和'setitimer()'。因此,「過時」功能有可用性。類似的評論適用於'gettimeofday()'和'clock_gettime()' - Mac OS X具有前者,但POSIX更喜歡後者,並將前者標記爲過時。 –

1

對於音頻/視頻通常您不需要納秒/微秒精度計時器,毫秒就足夠了。音頻中最常見的分組間間隔爲20ms。爲此目的使用nanosleep是個好習慣。

此外,除非您使用實時操作系統,否則無法保證從內核獲得如此好的時序。

在實時通信中使用睡眠的缺點是:它們沒有保持適當的頻率(對於20ms間隔的音頻爲50Hz)。因爲每次打勾都會將處理時間添加到睡眠間隔。所以睡眠時間間隔必須根據先前的時間戳記和下一個預期的時間戳記時間戳來計算。

您可以實現短時間間隔定時器(例如10毫秒),並在定時器警報發生此定時器警報之間發生睡眠和處理事件。如果你這樣做,你將優化操作系統資源使用(最小化進程/線程上下文切換)。