Вопрос по windows – Дрейф часов на Windows

15

Я разработал службу Windows, которая отслеживает деловые события. Он использует часы Windows для отметки времени событий. Тем не менее, лежащие в основе часы могут довольно сильно дрейфовать (например, терять несколько секунд в минуту), особенно когда процессоры усердно работают. Наши серверы используют службу времени Windows, чтобы поддерживать синхронизацию с контроллерами домена, которая использует NTP под капотом, но частота синхронизации контролируется политикой домена, и в любом случае даже синхронизация каждую минуту все равно допускает существенный сдвиг. Есть ли какие-либо методы, которые мы можем использовать для поддержания стабильности часов, кроме использования аппаратных часов?

Вы можете испытыватьMicrosoft Minute. jww
Похоже, это вопрос, связанный с программированием Mark
Дрейф часов, равный нескольким секундам в минуту, - это сломанные часы, неважно, насколько усердно работает машина. Вам нужно новое оборудование. skaffman
Вы не должны получать несколько секунд каждую минуту. Что-то не так с часами. Или у вас есть две программные службы, играющие с временем на машине и меняющие его из разностных источников? Matt
Это на самом деле не вопрос, связанный с программированием, поэтому я не уверен, относится ли он к StackOverflow. Outlaw Programmer

Ваш Ответ

13   ответов
5

w32tm / resync & quot; в запланированном задании .bat файл. Это работает на Windows Server 2003.

0

что служба времени Windows реализует только SNTP, который является упрощенной версией NTP. Полная реализация NTP учитывает стабильность ваших часов при принятии решения о частоте синхронизации.

Вы можете получитьполный NTP сервер для Windows здесь.

Windows 2000 была последней версией, которая все еще использовала SNTPtechnet.microsoft.com/en-us/library/…
2

Другое решение, которое не требует модификации кода, - добавление аргумента VM.-XX:+ForceTimeHighResolution (найдено наСтраница поддержки NTP).

9.2.3. Windows and Sun's Java Virtual Machine

Sun's Java Virtual Machine needs to be started with the >-XX:+ForceTimeHighResolution parameter to avoid losing interrupts.

See http://www.macromedia.com/support/coldfusion/ts/documents/createuuid_clock_speed.htm for more information.

По ссылочной ссылке (черезWayback машина - оригинальная ссылка исчезла):

ColdFusion MX: CreateUUID Increases the Windows System Clock Speed

Calling the createUUID function multiple times under load in Macromedia ColdFusion MX and higher can cause the Windows system clock to accelerate. This is an issue with the Java Virtual Machine (JVM) in which Thread.sleep calls less than 10 milliseconds (ms) causes the Windows system clock to run faster. This behavior was originally filed as Sun Java Bug 4500388 (developer.java.sun.com/developer/bugParade/bugs/4500388.html) and has been confirmed for the 1.3.x and 1.4.x JVMs.

In ColdFusion MX, the createUUID function has an internal Thread.sleep call of 1 millisecond. When createUUID is heavily utilized, the Windows system clock will gain several seconds per minute. The rate of acceleration is proportional to the number of createUUID calls and the load on the ColdFusion MX server. Macromedia has observed this behavior in ColdFusion MX and higher on Windows XP, 2000, and 2003 systems.

0

когда я сталкивался с этим, с включенной Spread Spectrum FSB, вызывает некоторые проблемы с синхронизацией прерываний, из-за чего эти тактовые частоты тикают. Возможно, вы захотите увидеть, является ли эта опция в BIOS на одном из этих серверов, и отключите ее, если она включена.

Другой вариант, который у вас есть, - отредактировать интервал опроса времени и сделать его намного короче, используя следующий раздел реестра. Скорее всего, вам придется его добавить (обратите внимание, что это значение DWORD, а значение указывается в секундах, например 600 в течение 10 минут) :

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

Вот полная обработка этого:KB816042

12

Проблема с Windows связана с тем, что при изменении разрешения таймера с помощьюtimeBeginPeriod () много, часы будут дрейфовать.

На самом деле, есть ошибка в потоке Javawait() (иos::sleep()) реализация функции Windows, которая вызывает такое поведение. Он всегда устанавливает разрешение таймера равным 1 мс перед ожиданием, чтобы быть точным (независимо от продолжительности ожидания), и восстанавливает его сразу после завершения, если другие потоки еще не спят. Этот набор / сброс затем запутает часы Windows, которые ожидают, что квант времени Windows будет довольно постоянным.

Солнце на самом делеоб этом известно с 2006 годаи не исправил это, УДАЧИ!

Из-за этого у нас на самом деле часы шли в два раза быстрее! Простая Java-программа, которая спит 1 миллисекунд в цикле, демонстрирует это поведение.

Решение состоит в том, чтобы установить временное разрешение самостоятельно на что-то низкое и сохранять его там как можно дольше. Используйте timeBeginPeriod () для управления этим. (Мы установили его на 1 мс без каких-либо побочных эффектов.)

Для тех, кто программирует на Java, проще всего это исправить, создав поток, который спит до тех пор, пока приложение живет.

Note that this will fix this issue on the machine globally, regardless of which application is the actual culprit.

@ Vincent: Относится к любому приложению Windows, которое вызывает timeBeginPeriod () с различными значениями и часто.
@ deed02392: кажется, что время движется медленнее, когда вы работаете с Java. Это как застрять в 90-х. ;-п
Вопрос: применимо ли это только к java, или Delphi или C # могут вызывать похожие проблемы, когда возятся с таймерами?
Ух ты. Я медленно работаю в течение нескольких ЧАСОВ в день и интенсивно работаю с Java ...
17

because они не предназначены для систем реального времени - другие прерывания устройства ввода-вывода имеют приоритет над прерыванием тактового сигнала, и некоторые драйверы выполняют обширную обработку в процедуре обслуживания прерываний, а не откладывают ее наотложенный вызов процедуры (DPC), что означает, что система может быть не в состоянии обслуживать прерывание тактового сигнала до (иногда) долгое время после того, как оно было передано.

К другим факторам относятся контроллеры ввода / вывода с мастерингом шины, которые крадут много тактов шины памяти у ЦП, в результате чего он в течение значительных периодов испытывает недостаток пропускной способности шины памяти.

Как уже говорили другие, аппаратные средства генерации тактовых импульсов также могут изменять свою частоту при изменении значений компонентов в зависимости от температуры.

Windows позволяет регулировать количество тиков, добавляемых к часам реального времени при каждом прерывании: см. SetSystemTimeAdjustment. Однако это сработает, только если у вас будет предсказуемый перекос часов. Если часы отключены лишь незначительно, клиент SNTP (служба «Windows Time») отрегулирует этот перекос, чтобы тактовая метка немного ускорялась или замедлялась для достижения точного времени.

1

Возьмите старый ноутбук или что-то, что не очень хорошо для многих, но, кажется, имеет более или менее надежные часы, и назовите его Timekeeper. Единственная задача Хронометриста состоит в том, чтобы один раз каждые (скажем) 2 минуты отправлять на сервер сообщения с указанием времени. Вместо того чтобы использовать часы Windows для своих временных меток, серверы будут записывать время с последнего сигнала хронометриста плюс время, прошедшее с момента получения сигнала. Проверяйте часы хронометриста у своих наручных часов один или два раза в неделю. Этого должно быть достаточно.

4

я не думаю, что вы можете многое сделать, кроме как приобрести новую материнскую плату, поскольку ваш тактовый сигнал, кажется, не на правильной частоте.

1

Записи реестра для сервиса W32Timeособенно «Период». & Quot; SpecialSkew & Quot; Похоже, это поможет вам.

0

ремени. Это наклеено ниже. Теперь, когда я вижу & quot; w32tm & quot; Команда, упомянутая Ларри Сильверманом, я подозреваю, что потратила впустую свое время.

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.
1

Если синхронизация выполняется с вашим собственным главным сервером в вашей собственной сети, нет причин не выполнять синхронизацию каждую минуту.

1

возможно, вы могли бы попытаться получить более постоянную температуру - возможно, используя лучшее охлаждение? Вы никогда не потеряете дрейфа полностью.

Использование внешних часов (приемник GPS и т. Д.) И статистического метода для привязки времени ЦП к абсолютному времени - вот что мы используем здесь для синхронизации событий в распределенных системах.

2

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

PC clocks should typically be accurate to within a few seconds per day. If you're experiencing massive clock drift-- on the order of minutes per day-- the first thing to check is your source of AC power. I've personally observed systems with a UPS plugged into another UPS (this is a no-no, by the way) that gained minutes per day. Removing the unnecessary UPS from the chain fixed the time problem. I am no hardware engineer, but I'm guessing that some timing signal in the power is used by the real-time clock chip on the motherboard.

Похожие вопросы