Форум: "Начинающим";
Текущий архив: 2010.03.21;
Скачать: [xml.tar.bz2];
ВнизCriticalSection Найти похожие ветки
← →
Sha © (2010-01-21 21:52) [40]> Демо © (21.01.10 21:49) [39]
Ага.
← →
Демо © (2010-01-21 21:52) [41]
> Sha ©
Не буду спорить. Ты прав. Но автору бы почитать сначала что-нибудь.
← →
Демо © (2010-01-21 21:53) [42]
> Или нужно опять защищать ? Т.е. так :EnterCriticalSection(CS);
> PostMessage(FMainHandle,WM_USER+99,wParam(FCountConnect),
> 0);LeaveCriticalSection(CS);
Вот это совершенно неверная идея. Непонятно что хочет автор.
← →
Anatoly Podgoretsky © (2010-01-21 22:08) [43]> Демо (21.01.2010 21:49:39) [39]
А как иначе ты предстваляешь?
← →
Дмитрий Белькевич (2010-01-22 00:24) [44]>А какое возможно исключение в коде Inc(FCountConnect) ?
Исключение, как это не парадоксально, может присутствовать практически в любой строчке кода. Включаем overflow/range checking и получаем замечательное исключение на "ровном" месте. В самый неподходящий момент, само собой.
Так что лучше, если делать именно Dec(FCountConnect), то так и делать:
EnterCriticalSection(CS);
Try
Dec(FCountConnect); // или Inc
Finally
LeaveCriticalSection(CS);
end;
Или отказаться от Dec(FCountConnect).
>Даже когда возможно исключение, выполнение в finally LeaveCriticalSection в приводит к довольно трудно диагностируемым ошибкам
Кгхм, а как же иначе вообще писать? Исключение внутри - и всё - внутрь мы уже никогда больше не зайдём.
Какие ошибки возможны? Я у себя всегда try/finally работу с секциями защищаю. Ни разу пока проблем (именно с try/finally) не было. Повезло, конечно, может.
← →
Игорь Шевченко © (2010-01-22 00:52) [45]Дмитрий Белькевич (22.01.10 00:24) [44]
> Кгхм, а как же иначе вообще писать?
А так и писать, с расчетом на то, что исключение может произойти в любой строке кода.
Вообще, разработка, управляемая исключениями, не так проста, как кажется на первый взгляд.
Секция finally изначально предназначалась для очистки ресурсов, файл закрыть, память освободить, то есть, логика, привносимая в код компилятором, гарантировала выполнение кода в любом случае, как при исключении, так и при нормальном завершении. А что в такой секции обчно делают - освобождают ресурсы во избежание утечки. А вовсе не дать остальным потокам/процессам доступ к несогласованным данным.
Ты вроде с базами общаешься, вот представь, что у тебя есть транзакция из нескольких операторов в таком виде:
try
insert into foo1 values (bar1,bar2);
insert into foo2 values (bar3,bar4);
delete from bazz where bar5 = foo;
finally
commit
end;
и если произошло исключение во втором или в третьем операторе, данные будут несогласованы.
Ту же самую логику ты закладываешь, вызывая LeaveCriticalSection в finally
> Какие ошибки возможны? Я у себя всегда try/finally работу
> с секциями защищаю. Ни разу пока проблем (именно с try/finally)
> не было. Повезло, конечно, может.
"Очистка после исключения, возбуждённого в коде, владеющим критической секцией, поднимает вопрос: "как вы узнаете, что именно безопасно очищать?". Вы завели критическую секцию для работы с какими-то данными. Критическая секция защищает ваши данные, пока вы изменяете их, т.е. переводите их в некоторое нестабильное состояние и не хотите, чтобы другие видели эти данные в такой несогласованной форме. Но если у вас появляется исключение во время работы внутри критической секции - ну, ваши данные в момент возбуждения исключения находятся в некорректном состоянии. Простой выход из критической секции оставит ваши данные в недопустимом состоянии, которое может привести к более трудно диагностируемым проблемам потом: "как это мой счётчик сумел сбиться?"."
http://transl-gunsmoker.blogspot.com/2008/12/blog-post_7745.html
(процитирован последний абзац)
← →
Дмитрий Белькевич (2010-01-22 02:05) [46]Спасибо, ясно.
>которое может привести к более трудно диагностируемым проблемам потом
В случае ошибки происходит же не черте-что, а целое исключение. Исключения же try/finally не ловит и не скрывает. И с диагностикой вроде бы никаких проблем.
Тут, конечно, вопрос открытый - стоит ли после исключения разрешать приложению работать или нет. В случае если try/finally не делать - то в секцию больше никто не зайдёт. И приложение окажется полностью или частично неработоспособным. В случае же try/finally есть надежда, что приложение нормально продолжит работу, хотя гарантировать это в общем случае нельзя.
← →
Дмитрий С © (2010-01-22 05:31) [47]inc (...) может исключение AV вызвать, разве нет?
← →
Anatoly Podgoretsky © (2010-01-22 08:57) [48]
> Ну, например, lock inc очень часто используется в строковых
> функция Delphi RTL.
Наверно с целью оптимизации, как inline без лишних движений. Но то что позволено Юпитеру, не позволено быку. Прикладному програмисту лучше стоит двигаться по ровной дороге.
← →
Anatoly Podgoretsky © (2010-01-22 09:01) [49]
> Игорь Шевченко © (22.01.10 00:52) [45]
> try
> insert into foo1 values (bar1,bar2);
> insert into foo2 values (bar3,bar4);
> delete from bazz where bar5 = foo;
> finally
> commit
> end;
Потому что этот код должен быть иначе и с другой защищеной секцией, стандартная форма обработки транзакций выглядит вот так:>
try
insert into foo1 values (bar1,bar2);
insert into foo2 values (bar3,bar4);
delete from bazz where bar5 = foo;
commit;
except
rollback;
end;
← →
Неважно (2010-01-22 10:37) [50]
> Ты прав. Но автору бы почитать сначала что-нибудь.
Я то читаю.
> Вот это совершенно неверная идея. Непонятно что хочет автор.
Да иди ты )) Что ж тут непонятного ?
← →
Демо © (2010-01-22 10:58) [51]
> Да иди ты )) Что ж тут непонятного ?
> PostMessage(FMainHandle,WM_USER+99,wParam(FCountConnect),
> 0);
Непонятно, что ты хочешь сделать в этом коде.
← →
Демо © (2010-01-22 11:01) [52]
> Anatoly Podgoretsky © (21.01.10 22:08) [43]
> > Демо (21.01.2010 21:49:39) [39]А как иначе ты предстваляешь?
>
Вроде понял. Автор желает отослать значение в основной поток.
Блин. Что-то 2 дня доходило. Наверное съел чего-нибудь.
← →
Игорь Шевченко © (2010-01-22 16:48) [53]Anatoly Podgoretsky © (22.01.10 09:01) [49]
Хитрый
← →
GanibalLector © (2010-01-22 17:55) [54]
> Секция finally изначально предназначалась для очистки ресурсов,
> файл закрыть, память освободить, то есть, логика, привносимая
> в код компилятором, гарантировала выполнение кода в любом
> случае, как при исключении, так и при нормальном завершении.
> А что в такой секции обчно делают - освобождают ресурсы
> во избежание утечки. А вовсе не дать остальным потокам/процессам
> доступ к несогласованным данным.
Кстати, в генофонде обрамляется в try finally.
function CheckSynchronize(Timeout: Integer = 0): Boolean;
var
SyncProc: PSyncProc;
LocalSyncList: TList;
begin
if GetCurrentThreadID <> MainThreadID then
raise EThread.CreateResFmt(@SCheckSynchronizeError, [GetCurrentThreadID]);
if Timeout > 0 then
WaitForSyncEvent(Timeout)
else
ResetSyncEvent;
LocalSyncList := nil;
EnterCriticalSection(ThreadLock);
try
Integer(LocalSyncList) := InterlockedExchange(Integer(SyncList), Integer(LocalSyncList));
try
Result := (LocalSyncList <> nil) and (LocalSyncList.Count > 0);
if Result then
begin
while LocalSyncList.Count > 0 do
begin
SyncProc := LocalSyncList[0];
LocalSyncList.Delete(0);
LeaveCriticalSection(ThreadLock);
try
try
SyncProc.SyncRec.FMethod;
except
SyncProc.SyncRec.FSynchronizeException := AcquireExceptionObject;
end;
finally
EnterCriticalSection(ThreadLock);
end;
SetEvent(SyncProc.signal);
end;
end;
finally
LocalSyncList.Free;
end;
finally
LeaveCriticalSection(ThreadLock);
end;
end;
← →
Игорь Шевченко © (2010-01-22 18:58) [55]LeaveCriticalSection(ThreadLock);
try
try
SyncProc.SyncRec.FMethod;
except
SyncProc.SyncRec.FSynchronizeException := AcquireExceptionObject;
end;
finally
EnterCriticalSection(ThreadLock);
end;
И нафиг здесь finally ?
function AcquireExceptionObject: Pointer;
asm
CALL CurrentException
OR EAX, EAX
JE @@Error
INC [EAX].TRaisedException.RefCount
MOV EAX, [EAX].TRaisedException.ExceptObject
RET
@@Error:
{ This happens if there is no exception pending }
JMP _Run0Error
end;
Я не вижу причины для исключения в функции AcquireExceptionObject, текущий Exception наличествует, так как вызов идет из секции except,
функции
function CurrentException: PRaisedException;
asm
CALL SysInit.@GetTLS
LEA EDX, [EAX].ExceptionObjects
MOV EAX, [EAX].ExceptionObjectCount
OR EAX, EAX
JE @@Done
DEC EAX
IMUL EAX, TRAISEDEXCEPTION_SIZE
ADD EAX, EDX
JMP @@Exit
@@Done:
CALL SysInit.@GetTLS
MOV EAX,[EAX].ExceptionList
@@Exit:
end;
вроде тоже на первый взгляд негде возбуждать исключение
Страницы: 1 2 вся ветка
Форум: "Начинающим";
Текущий архив: 2010.03.21;
Скачать: [xml.tar.bz2];
Память: 0.57 MB
Время: 0.006 c