Relógio à deriva nas janelas
13 answers
Relógio carrapatos deve ser previsível, mas na maioria do hardware do PC - porque eles não são projetados para sistemas de tempo real - outro dispositivo de e/S interrupções têm prioridade sobre o relógio tick interrupt (interrupção, e alguns drivers de fazer uma extensa transformação na rotina de serviço de interrupção, em vez de remetê-la para um chamada de procedimento deferidas (DPC), o que significa que o sistema pode não ser capaz de servir o clock tick interrupt (interrupção até que (às vezes) muito tempo depois ele foi sinalizado.
Outros factores incluem controladores de I/O que roubam muitos ciclos de barramento de memória da CPU, fazendo com que ela seja carente de largura de banda de barramento de memória por períodos significativos.
Como outros já disseram, o hardware de geração de relógios também pode variar a sua frequência à medida que os valores dos componentes mudam com a temperatura.O Windows permite ajustar a quantidade de carrapatos adicionados ao relógio em tempo real em cada interrupção: ver ajuste de tempo do sistema Set. Isto só funcionaria se tivesses um relógio previsível, entanto. Se o relógio estiver apenas ligeiramente desligado, o cliente SNTP (Serviço"tempo do Windows") irá ajustar este desvio para fazer o relógio marcar um pouco mais rápido ou mais lento para a tendência para o tempo correto.
Há um problema com o Windows que se você mudar a resolução do temporizador com o período de tempo() muito, o relógio irá rodar.
Na verdade, existe um bug no tópico de Java {[[0]} (e na implementação do Windows da função os::sleep()
que causa este comportamento. Ele sempre configura a resolução do temporizador para 1 ms antes de esperar, a fim de ser preciso (independentemente do comprimento de latência), e restaura-lo imediatamente após a conclusão, a menos que qualquer outros fios ainda estão a dormir. Este conjunto / reset irá então confundir o relógio do Windows, que espera que o tempo quântico do windows seja bastante constante.
A Sun tem realmente conhecimento disto desde 2006 {[[7]}, e não o consertou, em nada!
Tínhamos o relógio a andar duas vezes mais rápido por causa disto! Um simples programa Java que dorme 1 milisec em um loop mostra este comportamento.A solução é definir a resolução do tempo você mesmo, para algo baixo, e mantê-lo lá o máximo possível. Usar o período de tempo () para controlar isso. (Nós ajustamos para 1 ms sem quaisquer efeitos adversos.)
Para aqueles que codificam em Java, a maneira mais fácil de corrigir isso é criando um thread que dorme enquanto o aplicativo vive.
Note que isso vai corrigir este problema na máquina globalmente, independentemente de qual aplicação é o verdadeiro culpado.
Você poderia executar "w32tm / resync" em uma tarefa agendada .bat file. Isto funciona no Windows Server 2003.
Http://www.codinghorror.com/blog/2007/01/keeping-time-on-the-pc.html
Os relógios PC devem ter uma precisão de alguns segundos por dia. Se você está experimentando uma grande deriva de relógio-- na ordem de minutos por dia-- a primeira coisa a verificar é sua fonte de energia AC. Eu observei pessoalmente sistemas com um UPS plugado em outros UPS (este é um Não-Não, a propósito) que ganhou minutos por dia. Removendo os UPS desnecessários da cadeia consertou o problema de tempo. Não sou engenheiro de hardware, mas acho que algum sinal de tempo no poder é usado pelo chip do relógio em tempo real na placa-mãe.
Como já mencionado, os programas Java podem causar este problema.
Outra solução que não necessita de modificação de código é adicionar o argumento VM -XX:+ForceTimeHighResolution
(encontrado na página de suporte NTP).
9.2.3. Windows and Sun's Java Virtual Machine
A máquina virtual Java do Sun precisa de ser iniciada com o parâmetro >-XX:+forçar a alta resolução para evitar a perda de interrupções.
Ver http://www.macromedia.com/support/coldfusion/ts/documents/createuuid_clock_speed.htm para mais informações.
A partir da ligação referenciada (através da máquina Wayback - a ligação original desapareceu):
ColdFusion MX: CreateUUID aumenta a velocidade do relógio do sistema Windows
Chamando a função createUUID várias vezes sob carga em Macromedia ColdFusion MX e superior pode causar o relógio do sistema Windows acelerar. Este é um problema com a máquina virtual Java (JVM) em que Fio.as chamadas de sono inferiores a 10 milisegundos (ms) causam a Relógio do sistema Windows para correr mais rápido. Este comportamento foi originalmente arquivado como Sun Java Bug 4500388 (developer.java.sun.com/developer/bugParade/bugs/4500388.html) e tem confirmado para o 1.3.x e 1.4.X JVMs.
Na ColdFusion MX, a função createUUID tem uma linha interna.sono chamada de 1 milissegundo. Quando o createUUID é fortemente utilizado, o Relógio do sistema Windows vai ganhar vários segundos por minuto. A taxa de a aceleração é proporcional ao número de chamadas createUUID e ao carrega no servidor MX ColdFusion. Macromedia observou este comportamento em ColdFusion MX e superior no Windows XP, 2000, e 2003 sistema.
Usando um relógio externo (receptor GPS, etc...), e um método estatístico para relacionar o tempo de CPU com o tempo absoluto é o que usamos aqui para sincronizar eventos em sistemas distribuídos.
Outra opção que você tem é editar o intervalo de tempo de votação e torná-lo muito mais curto usando a seguinte chave de registro, o mais provável é que você terá que adicioná-lo (note que este é um valor DWORD e o valor é em segundos, por exemplo 600 para 10min):
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpClient\SpecialPollInterval
Aqui está um trabalho completo.: KB816042
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.
Eu acredito que o Windows Time Service apenas implementa o SNTP, que é uma versão simplificada do NTP. Uma implementação NTP completa leva em conta a estabilidade do seu relógio para decidir com que frequência sincronizar.
Pode obter o servidor NTP completo para o Windows aqui .