Дрейф часов в Windows

Дополнить ответ на основе LINQ собственным решением PowerShell :

Командлет Compare-Object позволяет сравнивать коллекции , но обратите внимание, что хотя он более краткий , он также намного медленнее, чем решение на основе LINQ :

Compare-Object -PassThru -Property FindName1 `
  ([Data.DataRow[]] $Table1.Rows) `
  ([Data.DataRow[]] $Table2.Rows) | Where-Object SideIndicator -eq '<='
  • Casting [Data.DataRow[]] - который создает новый массив из коллекции строк - по-видимому, необходим для Compare-Object распознавания строк как перечислимых.

    • Вызов .GetEnumerator() или приведение к Collections.IEnumerable не помогают, а приведение к Collections.Generic.IEnumerable[Data.DataRow]] не удается.
  • -Property FindName1 задает свойство сравнения, то есть свойство для сравнения строк по.

  • -PassThru необходимо, чтобы Compare-Object выводил входные объекты как есть, вместо пользовательских объектов, которые содержат только свойства, указанные в -Property.

    • Обратите внимание, что объекты украшены элементом NoteProperty .SideIndicator, однако, с помощью ETS (расширенной системы типов) PowerShell - см. Ниже.
  • Учитывая, что Compare-Object выводит входные объекты, которые являются уникальными для или коллекции , Where-Object SideIndicator -eq '<=' необходимо использовать для ограничения результатов теми разностными объектами, которые являются уникальными на входную коллекцию LHS (которая сигнализируется через значение свойства .SideIndicator, равное '<=' - стрелка указывает в сторону, для которой объект уникален).

В этом выпуске GitHub предлагается ряд улучшений командлета Compare-Object, которые могут помочь упростить и ускорить приведенное выше решение.
Тем не менее, предложение сделать LINQ первоклассным гражданином PowerShell имеет гораздо большие перспективы.

15
задан Matt Howells 19 September 2008 в 14:34
поделиться

11 ответов

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

1
ответ дан 1 December 2019 в 00:33
поделиться

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

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

1
ответ дан 1 December 2019 в 00:33
поделиться

Синхронизация чаще. Посмотрите эти Ключи реестра для сервиса W32Time , особенно "Период". "SpecialSkew" кажется, что помог бы Вам.

1
ответ дан 1 December 2019 в 00:33
поделиться

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

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

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

Вот полный workup на нем: KB816042

0
ответ дан 1 December 2019 в 00:33
поделиться

Я однажды записал класс Delphi во время обработки resynchs. Это вставляется ниже. Теперь, когда я вижу команду "w32tm", упомянутую Larry Silverman, я подозреваю, что потратил впустую свое время.

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.
0
ответ дан 1 December 2019 в 00:33
поделиться

Я полагаю, что Windows Time Service только реализует SNTP, который является упрощенной версией NTP. Полная реализация NTP принимает во внимание устойчивость Ваших часов в решении, как часто синхронизировать.

можно добраться полный сервер NTP для Windows здесь .

0
ответ дан 1 December 2019 в 00:33
поделиться

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

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

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

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

17
ответ дан 1 December 2019 в 00:33
поделиться

Я не знаю, применяется ли это, но...

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

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

Sun на самом деле знал об этом с 2006 и не зафиксировал его, AFAICT!

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

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

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

Обратите внимание, что это устранит эту проблему на машине глобально, независимо от которой приложение является фактическим преступником.

12
ответ дан 1 December 2019 в 00:33
поделиться

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

4
ответ дан 1 December 2019 в 00:33
поделиться

Вы могли выполнить "пересинхронизацию w32tm /" в запланированной задаче .bat файл. Это работает над Windows Server 2003.

5
ответ дан 1 December 2019 в 00:33
поделиться

Поскольку это звучит так, будто у вас большой бизнес:

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

1
ответ дан 1 December 2019 в 00:33
поделиться
Другие вопросы по тегам:

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