tagger tag windows clock

windows - tagger - tag folders



Reloj a la deriva en Windows (13)

Desarrollé un servicio de Windows que rastrea eventos de negocios. Utiliza el reloj de Windows para eventos de marca de tiempo. Sin embargo, el reloj subyacente puede derivar bastante dramáticamente (por ejemplo, perder unos segundos por minuto), particularmente cuando las CPU están trabajando duro. Nuestros servidores usan el Servicio de hora de Windows para mantenerse sincronizados con los controladores de dominio, que usan NTP bajo el capó, pero la frecuencia de sincronización está controlada por la política de dominio, y en cualquier caso incluso sincronizar cada minuto todavía permitiría una deriva significativa. ¿Hay alguna técnica que podamos usar para mantener el reloj más estable, aparte de usar relojes de hardware?


No sé si esto aplica, pero ...

Existe un problema con Windows que si cambia mucho la resolución del temporizador con timeBeginPeriod () , el reloj se desplazará.

En realidad, hay un error en la implementación de Windows de la función Thread wait() (y la ejecución de os::sleep() ) de Java que causa este comportamiento. Siempre establece la resolución del temporizador en 1 ms antes de esperar para ser preciso (independientemente de la duración del sueño), y lo restaura inmediatamente después de la finalización, a menos que otros hilos sigan durmiendo. Este set / reset confundirá el reloj de Windows, que espera que el tiempo de Windows sea bastante constante.

Sun lo sabe desde 2006 y no lo ha solucionado, ¡AFAICT!

¡De hecho, tuvimos el reloj funcionando el doble de rápido debido a esto! Un simple programa de Java que duerme 1 milisegundo en un bucle muestra este comportamiento.

La solución es establecer la resolución del tiempo usted mismo, en algo bajo, y mantenerlo allí el mayor tiempo posible. Use timeBeginPeriod () para controlar eso. (Lo configuramos en 1 ms sin ningún efecto adverso).

Para aquellos que codifican en Java, la manera más fácil de solucionar esto es creando un hilo que duerme mientras viva la aplicación.

Tenga en cuenta que esto solucionará este problema en la máquina de forma global, independientemente de qué aplicación sea la verdadera culpable.


¿Qué servidores estás ejecutando? En los equipos de sobremesa, las veces que me he encontrado con Spread Spectrum FSB habilitado, causa algunos problemas con el tiempo de interrupción, que es lo que hace que ese reloj funcione. Puede querer ver si esta es una opción en el BIOS en uno de esos servidores y desactivarla si está habilitada.

Otra opción que tiene es editar el intervalo de sondeo de tiempo y hacerlo mucho más corto con la siguiente clave de registro, lo más probable es que tenga que agregarlo (tenga en cuenta que este es un valor DWORD y el valor está en segundos, por ejemplo 600 durante 10 minutos) :

HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/W32Time/TimeProviders/NtpClient/SpecialPollInterval

Aquí hay un análisis completo sobre el mismo: KB816042


Además de reactivar el reloj con más frecuencia, no creo que haya mucho que puedas hacer, aparte de obtener una placa base nueva, ya que la señal del reloj no parece estar en la frecuencia correcta.


Aumenta la frecuencia de la resincronización. Si las sincronizaciones son con su propio servidor principal en su propia red, no hay razón para no sincronizar cada minuto.


Creo que el Servicio de hora de Windows solo implementa SNTP, que es una versión simplificada de NTP. Una implementación completa de NTP tiene en cuenta la estabilidad de su reloj al decidir con qué frecuencia sincronizar.

Aquí puede obtener el servidor NTP completo para Windows .


La deriva del reloj puede ser una consecuencia de la temperatura; tal vez podrías intentar que la temperatura sea más constante, ¿quizás usando un mejor enfriamiento? Sin embargo, nunca va a perder la deriva totalmente.

El uso de un reloj externo (receptor GPS, etc ...) y un método estadístico para relacionar el tiempo de la CPU con el Tiempo Absoluto es lo que usamos aquí para sincronizar eventos en sistemas distribuidos.


Las marcas de reloj deben ser predecibles, pero en la mayoría de los equipos de PC, porque no están diseñados para sistemas en tiempo real, otras interrupciones de dispositivo de E / S tienen prioridad sobre la interrupción de reloj, y algunos controladores realizan un procesamiento extenso en la rutina de servicio de interrupción que lo deferir a una llamada de procedimiento diferido (DPC), lo que significa que el sistema puede no ser capaz de servir la interrupción de marca de reloj hasta (a veces) mucho después de que fue señalado.

Otros factores incluyen los controladores de E / S de bus-mastering que roban muchos ciclos de bus de memoria de la CPU, lo que hace que se anule el ancho de banda del bus de memoria durante períodos significativos.

Como otros han dicho, el hardware de generación de reloj también puede variar su frecuencia a medida que los valores de los componentes cambian con la temperatura.

Windows permite ajustar la cantidad de tics agregados al reloj en tiempo real en cada interrupción: consulte SetSystemTimeAdjustment. Sin embargo, esto solo funcionaría si tuvieras un sesgo de reloj predecible. Si el reloj está solo un poco apagado, el cliente SNTP (servicio "Tiempo de Windows") ajustará esta inclinación para hacer que el reloj marque un poco más rápido o más lento para ir hacia la hora correcta.


Puede ejecutar "w32tm / resync" en un archivo .bat de tarea programada. Esto funciona en Windows Server 2003.



Una vez escribí una clase Delphi para manejar resynchs de tiempo. Está pegado a continuación. Ahora que veo el comando "w32tm" mencionado por Larry Silverman, sospecho que perdí el tiempo.

unit TimeHandler; interface type TTimeHandler = class private FServerName : widestring; public constructor Create(servername : widestring); function RemoteSystemTime : TDateTime; procedure SetLocalSystemTime(settotime : TDateTime); end; implementation uses Windows, SysUtils, Messages; function NetRemoteTOD(ServerName :PWideChar; var buffer :pointer) : integer; stdcall; external ''netapi32.dll''; function NetApiBufferFree(buffer : Pointer) : integer; stdcall; external ''netapi32.dll''; type //See MSDN documentation on the TIME_OF_DAY_INFO structure. PTime_Of_Day_Info = ^TTime_Of_Day_Info; TTime_Of_Day_Info = record ElapsedDate : integer; Milliseconds : integer; Hours : integer; Minutes : integer; Seconds : integer; HundredthsOfSeconds : integer; TimeZone : LongInt; TimeInterval : integer; Day : integer; Month : integer; Year : integer; DayOfWeek : integer; end; constructor TTimeHandler.Create(servername: widestring); begin inherited Create; FServerName := servername; end; function TTimeHandler.RemoteSystemTime: TDateTime; var Buffer : pointer; Rek : PTime_Of_Day_Info; DateOnly, TimeOnly : TDateTime; timezone : integer; begin //if the call is successful... if 0 = NetRemoteTOD(PWideChar(FServerName),Buffer) then begin //store the time of day info in our special buffer structure Rek := PTime_Of_Day_Info(Buffer); //windows time is in GMT, so we adjust for our current time zone if Rek.TimeZone <> -1 then timezone := Rek.TimeZone div 60 else timezone := 0; //decode the date from integers into TDateTimes //assume zero milliseconds try DateOnly := EncodeDate(Rek.Year,Rek.Month,Rek.Day); TimeOnly := EncodeTime(Rek.Hours,Rek.Minutes,Rek.Seconds,0); except on e : exception do raise Exception.Create( ''Date retrieved from server, but it was invalid!'' + #13#10 + e.Message ); end; //translate the time into a TDateTime //apply any time zone adjustment and return the result Result := DateOnly + TimeOnly - (timezone / 24); end //if call was successful else begin raise Exception.Create(''Time retrieval failed from "''+FServerName+''"''); end; //free the data structure we created NetApiBufferFree(Buffer); end; procedure TTimeHandler.SetLocalSystemTime(settotime: TDateTime); var SystemTime : TSystemTime; begin DateTimeToSystemTime(settotime,SystemTime); SetLocalTime(SystemTime); //tell windows that the time changed PostMessage(HWND_BROADCAST,WM_TIMECHANGE,0,0); end; end.


Ya que parece que tienes un gran negocio:

Tome una computadora portátil vieja o algo que no es bueno para mucho, pero parece tener un reloj más o menos confiable, y llámelo Timekeeper. El único trabajo del Timekeeper es, una vez cada (digamos) 2 minutos, enviar un mensaje a los servidores que dicen la hora. En lugar de usar el reloj de Windows para sus marcas de tiempo, los servidores disminuirán el tiempo de la última señal del Timekeeper, más el tiempo transcurrido desde la señal. Verifique el reloj del cronometrador con su reloj de pulsera una o dos veces por semana. Esto debería ser suficiente.


http://www.codinghorror.com/blog/2007/01/ keeping-time-on-the-pc.html

Los relojes de PC generalmente deben ser precisos en unos pocos segundos por día. Si está experimentando una desviación masiva del reloj, del orden de minutos por día, lo primero que debe verificar es su fuente de alimentación de CA. Personalmente, he observado sistemas con un SAI conectado a otro SAI (este es un no-no, por cierto) que ganaba minutos por día. La eliminación del UPS innecesario de la cadena solucionó el problema del tiempo. No soy ingeniero de hardware, pero supongo que el chip de reloj en tiempo real de la placa base utiliza alguna señal de temporización en el poder.


Como ya se mencionó, los programas de Java pueden causar este problema.

Otra solución que no requiere modificación de código es agregar el argumento VM -XX:+ForceTimeHighResolution (que se encuentra en la página de soporte de NTP ).

9.2.3. Windows y la máquina virtual Java de Sun

La máquina virtual Java de Sun debe iniciarse con el parámetro> -XX: + ForceTimeHighResolution para evitar la pérdida de interrupciones.

Consulte http://www.macromedia.com/support/coldfusion/ts/documents/createuuid_clock_speed.htm para obtener más información.

Desde el enlace al que se hace referencia (a través de la máquina Wayback - el enlace original se ha ido):

ColdFusion MX: CreateUUID aumenta la velocidad del reloj del sistema de Windows

Llamar a la función createUUID varias veces bajo carga en Macromedia ColdFusion MX y superior puede provocar que el reloj del sistema de Windows se acelere. Este es un problema con Java Virtual Machine (JVM) en el que Thread.sleep llama a menos de 10 milisegundos (ms) hace que el reloj del sistema Windows se ejecute más rápido. Este comportamiento se archivó originalmente como Sun Java Bug 4500388 (developer.java.sun.com/developer/bugParade/bugs/4500388.html) y se ha confirmado para las JVM 1.3.xy 1.4.x.

En ColdFusion MX, la función createUUID tiene una llamada Thread.sleep interna de 1 milisegundo. Cuando createUUID se utiliza en gran medida, el reloj del sistema de Windows ganará varios segundos por minuto. La velocidad de aceleración es proporcional al número de llamadas a createUUID y la carga en el servidor ColdFusion MX. Macromedia ha observado este comportamiento en ColdFusion MX y superior en los sistemas Windows XP, 2000 y 2003.