Цитата:
Сообщение от 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