Показать сообщение отдельно
  #5  
Старый 15.04.2018, 19:00
nixon232 nixon232 вне форума
Активный
 
Регистрация: 26.01.2014
Сообщения: 282
Версия Delphi: delphi xe4
Репутация: выкл
По умолчанию

Цитата:
Сообщение от dr. F.I.N.
Для просмотра флага входите в критическую секцию? Уверены, что при просмотре флага поток не успевает сменить его значение? А может флаг не нужен совсем? Какую логику работы вы "преследуете"? В каком месте кода вы работаете с данными и где проверяете флаг?
Вы правы, в реальном коде от этого отказался, за ненадобностью т.к. сам таймер предотвращает одновременное использование. Но для общего развития хотелось бы понять причину. Шансов на то, что не успевает записать, нету т.к. второй запрос идет спустя ~2 с, а сам запрос не затратный.
Сам поток правда в цикле крутится с такой паузой в цикле
Код:
...
begin
  while not Terminated do
  begin
    case WaitForMultipleObjects(2, @FHandles[0], False, INFINITE) of
      WAIT_FAILED:
        RaiseLastOsError;
      WAIT_OBJECT_0:
        Terminate;
      WAIT_OBJECT_0 + 1:
        begin
          WaitMe(400);
...
Код:
procedure WaitMe(msc: Cardinal);
var
  Ret: Dword;
  WaitTime: TLargeInteger;
  Timer: THandle;
begin
  // sleep  without freezing
  Timer := CreateWaitableTimer(nil, True, nil);
  WaitTime := -msc * 10000; 
  SetWaitableTimer(Timer, WaitTime, 0, nil, nil, false);
  repeat
  
    Ret := MsgWaitForMultipleObjects(1, Timer, false, INFINITE, QS_ALLINPUT);
    if Ret <> (WAIT_OBJECT_0 + 1) then
      Break;
    Application.ProcessMessages;
  until false;
  if Ret <> WAIT_OBJECT_0 then
    CancelWaitableTimer(Timer);
  CloseHandle(Timer);
end;
Проверяю флаг тут же, в InitWork
Код:
type
  TThr= class(TThread)
  private
    FHandles: array[0..1] of THandle;
    FLock: TCriticalSection;
    fOnTime: Boolean;
...
procedure TThr.InitWork(id: Cardinal);
begin
  FLock.Enter;
  try
    if not FOnTime then
    begin
      fOnTime:=True;
      ....
      fOnTime:=false;
 
    end;
 
  finally
    FLock.Leave
  end;
end;
то есть грубо говоря:
Код:
 Thr.initWork(1);/// fONTime =false, все ок, заходим, меняем флаг, работаем, меняем обратно
 Thr.initWork(2);/// fONTime =true 
Ответить с цитированием