2015-07-10 64 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毫秒),并在定时器警报发生此定时器警报之间发生睡眠和处理事件。如果你这样做,你将优化操作系统资源使用(最小化进程/线程上下文切换)。