我知道Sleep()
不准确,但有没有办法让它睡眠时间不超过10毫秒(即只睡1到10毫秒)?或者Sleep(1)
已经保证了吗?
答案 0 :(得分:3)
如果你真的想要保证时间安排,你根本就不会使用Windows。
要回答你的问题,Sleep()
没有提供任何保证睡眠时间上限的方法。
在Windows中,这是因为Sleep()
放弃了线程的时间片,并且不能保证系统调度程序将调度休眠线程(即分配另一个时间片)以在...之后立即执行。睡眠时间到了。这取决于竞争线程的优先级,调度策略等等。
实际上,实际的睡眠间隔很大程度上取决于系统上运行的其他程序,系统配置,其他程序是否正在访问慢速驱动器等等。
使用轻载系统,在任何现代(GHz频率CPU或更高频率)下,Sleep(1)
将在1到2毫秒之间休眠。但是,您的计划不可能遇到更大的延迟。
对于负载很重的系统(许多其他程序正在执行,使用CPU和计时器资源),可以肯定的是,您的程序将经历比1毫秒大得多的延迟,甚至超过10毫秒。
简而言之:没有保证。
答案 1 :(得分:1)
答案 2 :(得分:1)
不。 或者,是的,取决于您的观点。
休眠间隔过后,线程就可以运行了。如果 你指定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毫秒之间的响应时间。
如果你想要一个极高的精度,你必须将这个线程优先级提升到可能抢占它的其他任务之上,无论如何你可能仍会被系统进程和/或中断处理程序抢占,这会增加一些噪音你的计时器。