我已经开发了一个跟踪业务事件的Windows服务。它使用Windows时钟为事件加时间戳。但是,底层时钟可能会非常剧烈地漂移(例如,每分钟损失几秒钟),特别是当CPU正在努力工作时。我们的服务器使用Windows时间服务与域控制器保持同步,域控制器在幕后使用NTP,但同步频率由域策略控制,在任何情况下,即使每分钟同步也会允许显著的漂移。除了使用硬件时钟之外,我们还可以使用其他技术来保持时钟更稳定吗?
发布于 2008-09-19 15:33:05
时钟节拍应该是可预测的,但在大多数PC硬件上-因为它们不是为实时系统设计的-其他I/O设备中断的优先级高于时钟节拍中断,并且一些驱动程序在中断服务例程中进行大量处理,而不是将其推迟到deferred procedure call (DPC),这意味着系统可能直到(有时)在发出信号很长时间后才能服务于时钟节拍中断。
其他因素包括总线主控I/O控制器,它从CPU窃取许多内存总线周期,导致它在很长一段时间内内存总线带宽匮乏。
正如其他人所说的,时钟产生硬件也可以随着分量值随温度变化而改变其频率。
Windows允许调整每次中断时添加到实时时钟的节拍量:参见SetSystemTimeAdjustment。然而,只有当你有一个可预测的时钟偏差时,这才能起作用。如果时钟只是稍微偏离,SNTP客户端("Windows时间“服务)将调整这种偏差,使时钟稍微快一点或慢一点,使其趋向于正确的时间。
发布于 2009-03-08 21:34:46
我不知道这是否适用,但是...
Windows有一个问题,如果你用timeBeginPeriod()大量改变计时器的分辨率,时钟就会漂移。
实际上,在(和os::sleep()
)函数的wait()
实现中有一个bug导致了这种行为。它总是在等待之前将计时器分辨率设置为1毫秒,以便准确(无论休眠长度如何),并在完成后立即恢复,除非任何其他线程仍在休眠。此设置/重置将使Windows时钟混淆,该时钟期望窗口时间段相当恒定。
Sun实际上有known about this since 2006,并且还没有修复它,AFAICT!
正因为如此,我们的时钟实际上快了一倍!一个在循环中休眠1毫秒的简单Java程序显示了这种行为。
解决方案是自己设置时间分辨率,将其设置为较低的值,并尽可能长时间地保持该分辨率。使用timeBeginPeriod()来控制它。(我们将其设置为1ms,没有任何不利影响。)
对于那些用Java编写代码的人来说,解决这个问题的更简单的方法是创建一个在应用程序存在期间一直处于休眠状态的线程。
请注意,这将在计算机上全局修复此问题,而不管哪个应用程序是真正的罪魁祸首。
发布于 2008-09-19 14:19:55
您可以在计划任务.bat文件中运行"w32tm /resync“。这在Windows Server 2003上有效。
https://stackoverflow.com/questions/102064
复制相似问题