我可以保证Sleep()不会睡眠超过10毫秒吗?

时间:2015-02-20 22:13:05

标签: c++ winapi sleep

我知道Sleep()不准确,但有没有办法让它睡眠时间不超过10毫秒(即只睡1到10毫秒)?或者Sleep(1)已经保证了吗?

5 个答案:

答案 0 :(得分:3)

如果你真的想要保证时间安排,你根本就不会使用Windows。

要回答你的问题,Sleep()没有提供任何保证睡眠时间上限的方法。

在Windows中,这是因为Sleep()放弃了线程的时间片,并且不能保证系统调度程序将调度休眠线程(即分配另一个时间片)以在...之后立即执行。睡眠时间到了。这取决于竞争线程的优先级,调度策略等等。

实际上,实际的睡眠间隔很大程度上取决于系统上运行的其他程序,系统配置,其他程序是否正在访问慢速驱动器等等。

使用轻载系统,在任何现代(GHz频率CPU或更高频率)下,Sleep(1)将在1到2毫秒之间休眠。但是,您的计划不可能遇到更大的延迟。

对于负载很重的系统(许多其他程序正在执行,使用CPU和计时器资源),可以肯定的是,您的程序将经历比1毫秒大得多的延迟,甚至超过10毫秒。

简而言之:没有保证。

答案 1 :(得分:1)

没有办法保证。

这是real time OS的用途。

一般情况下,如果你的操作系统没有经历高负荷,那么睡眠会非常准确,但随着你增加负荷,它会得到更多的不准确。

答案 2 :(得分:1)

不。 或者,是的,取决于您的观点。

根据the documentation

  

休眠间隔过后,线程就可以运行了。如果   你指定0毫秒,线程将放弃余数   它的时间片但仍然准备好了。请注意,就绪线程不是   保证立即运行。因此,线程可能无法运行   直到睡眠间隔过去一段时间后。更多   信息,请参阅Scheduling Priorities

这意味着问题不是Sleep。相反,当Sleep结束时,您的主题可能仍需要等待再次变为活动状态。

答案 3 :(得分:1)

你不能指望10毫秒,这太低了。睡眠()准确度受以下因素影响:

  • 时钟滴答中断频率。通常,处理器倾向于处于静止状态,不消耗任何功率并且由HLT指令关闭。这对世界是死的,不知道时间过去了,并且没有意识到你的睡眠间隔已经过期。芯片组产生的周期性硬件中断将其唤醒并再次引起注意。默认情况下,此中断每秒生成64次。或者每15.625毫秒一次。

  • 线程调度程序在每个时钟中断运行。它注意到你的睡眠间隔已经过期,它会使线程回到准备运行状态。并提升其优先级,以便更有可能获得处理器核心。当没有其他具有更高优先级的线程准备好运行时,它将执行此操作。

关于第二颗子弹,你无能为力,你必须与其他人竞争并获得公平分享。如果该线程进行了大量的休眠和很少的计算,那么声称超过您的公平份额并不是不合理的,请致电SetThreadPriority()以提高您的基本优先级并使您的睡眠间隔更准确。如果这还不够好,那么获得足够高优先级的唯一方法就是通过编写ring 0代码,一个驱动程序。

你可以搞乱第一颗子弹,这是很常见的。也是许多程序员认为默认精度为10毫秒的原因。或者,如果他们使用的Chrome可能是1毫秒,那么浏览器会将中断率提升到最高点。这是一个相当不合理的事情,对功耗不利,除非你的业务是让你的移动操作系统产品看起来不错:)

在你需要让你的睡眠间隔足够短时调用timeBeginPeriod,在你完成时调用timeEndPeriod()。如果需要低于1毫秒,请使用NtSetTimerResolution()。

答案 4 :(得分:0)

Sleep不能保证。

我知道这样做的唯一方法是让线程等待快速定时器事件并每隔10毫秒左右释放一个同步对象。

您将信号量传递给此"等待服务器任务",它将在下一个计时器时间点释放它,从而为您提供0到10毫秒之间的响应时间。

如果你想要一个极高的精度,你必须将这个线程优先级提升到可能抢占它的其他任务之上,无论如何你可能仍会被系统进程和/或中断处理程序抢占,这会增加一些噪音你的计时器。