2013-10-17 22 views
3

我正在制定计时系统,我将实施一个计时器班。Sleep()是否不准确?

#include <windows.h> 
#include <stdio.h> 
#include <time.h> 

int main() 
{ 
    clock_t t1, t2; 
    t1 = clock(); 
    Sleep(10); 
    t2 = clock(); 
    printf("%i\n", (int)(t2 - t1)); 
    return 0; 
} 

该程序应打印“10”,但打印“15”或“16”。我需要更准确的,这是少于1毫秒!建议? (也许select()的超时?)

注意:我已经在Windows 7旗舰版x86上运行此程序。用MinGW(C/C++)x86编译的程序。

NOW I THINK >>

回答

3

睡眠()是精确到操作系统的时钟中断率。在Windows上,默认情况下,每秒钟处理64次。或者每15.625毫秒一次,正如你发现的那样。

您可以增加该费率,请致电timeBeginPeriod(10)。完成后使用timeEndPeriod(10)。您仍然受到正常线程调度延迟的影响,因此您仍然无法保证线程将在10毫秒后恢复运行。当机器重负荷时不会。使用SetThreadPriority()提高优先级,增加它的可能性。

+0

...甚至是timeBeginPeriod(1)。但是:更好地使用'TIMECAPS'结构的'wPeriodMin',由 填充[timeGetDevCaps](http://msdn.microsoft.com/en-us/library/windows/desktop/dd757627%28v=vs.85 %29.aspx)。 注意:结果周期取决于底层硬件。 – Arno

+0

只问你需要什么,使用1是浪费。最短的时间段并不重要,它已经自动调整,如果超过了你的需要,你就无法做任何事情。无论如何,最后一台不支持它的机器在15年前就死了。 –

+0

它比需要更多吗?睡眠(10)的调用在中断时可能不会总是发生**。在使用timeBeginPeriod(10)时,在下一个中断之前5 ms调用Sleep(10)将导致15 ms的总睡眠。 – Arno

1

Sleep()以您希望的方式不准确。

它会导致线程在您指定的时间内至少睡眠一次,但不能保证操作系统将在恰好指定的时间将控制权返回给您的线程。

1

你的问题是,“时钟”只有每秒64次(我见过的系统可以达到2000,但不会更高)。如果你正在创建一个计时器类,你可能想要有比2000更高的分辨率。使用QueryPerformanceCounter可以获得更高的分辨率。例如,请参阅QueryPerformanceCounter and overflows

请注意,如果您想睡非常很短的间隔,您将不得不在紧密循环中呼叫QueryPerformanceCounter

+0

跨平台? – PilawyerDev

+0

@PilawyerDev:不,这是仅限Windows。 – Gabe

+0

谢谢!没关系。我想我可以用信号处理和(阻塞/混合)队列来为我的定时器类和定时线程。 – PilawyerDev