![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Отловить ошибку в TThread [D7, WinXP]
Alex_C © (2007-08-09 13:26:00)Проблема: получаю данные из инета в отдельном потоке, чтоб не тормозить программу и отсылаю их в основную прогу. А вот если пользователь закрывает программу во время приема данных вылетает ошибка доступа - тут как бы все понятно - программы в памяти уже нет, а прием данных все продолжается и происходит обращение в никуда. Как этого избежать, кроме как не закрывать прогу до завершения приема данных? Пробовал в потоке ставить try... except - не помогает.
Прием данных осуществляю ф-цией InternetReadFile.
Leonid Troyanovsky (2007-08-11 12:15:00) [1]
> Alex_C © (10.08.07 17:33) [38]
> Делфи заставить ЦП обновить тот или иной кэш БЕЗ правки
> кода TThread ?
Кэши процессоров обновятся при изменении общей переменной,
в нашем случае - FTerminated без всякого вмешательства.
Во всяком случае, для Intel.
--
Regards, LVT.
Alex_C (2007-08-10 22:59:00) [2]То Lacmus: достойное решение! Завтра попробую опробировать на новом компе! Вот что называется простенько и со вкусом! Спасибо!
Lacmus (2007-08-10 18:02:00) [3]>Alex_C © (10.08.07 17:33) [38]
Да, треды будут запускаться на одном процессоре (думаю это будет адекватное решение)
Alex_C (2007-08-10 17:33:00) [4]Ну блин не ожидал такой полемики по поводу моего вопроса :)
К сожалению до конца не все ясно.
Конкретные попросы по вышепрочитанному:
То Сергей М.: не укажешь ли конкретно способы прямо в коде Делфи заставить ЦП обновить тот или иной кэш БЕЗ правки кода TThread ?
То Lacmus: SetProcessAffinityMask - это заставить процесс выполняться на конкретном процесоре. Т.е. ты предлагаешь изначально все треды запускать на одном проце, я так понимаю?
Lacmus (2007-08-10 16:28:00) [5]>Alex_C © (09.08.07 19:25) [8]
SetProcessAffinityMask
oxffff (2007-08-10 15:54:00) [6]Небольшая оптимизация
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
SetEvent(params.Sync);
while params.ThreadCount<length(Threads) do
begin
CheckSynchronize;
sleep(300);
end;
....
Showmessage...
end;
oxffff (2007-08-10 15:46:00) [7]Вот исправленный код.
ThreadParams=packed record
Sync:Thandle;
ThreadCount:DWORD;
end;
PThreadParams=^ThreadParams;
TForm1 = class(TForm)
Memo1: TMemo;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
params:ThreadParams;
public
{ Public declarations }
Threads:array[0..MAXIMUM_WAIT_OBJECTS-2] of THandle;
constructor Create(AOwner: TComponent);override;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure PendingCallInMainThread(Self:pointer);
begin
form1.Memo1.Lines.add('Thread works ');
end;
function ThreadProc(const params):DWORD;stdcall;
var Method:TMethod;
begin
Method.data:=nil;
Method.code:=@PendingCallInMainThread;
while WaitForSingleObject(ThreadParams(params).Sync,0)<>WAIT_OBJECT_0 do
begin
TThread.Synchronize(nil,TThreadMethod(Method));
sleep(1000);
end;
InterlockedIncrement(integer((@ThreadParams(params).ThreadCount)^));
end;
constructor TForm1.Create(AOwner: TComponent);
var i:integer;
tid:DWORD;
begin
inherited;
params.Sync:=CreateEvent(nil,TRUE,FALSE,nil);
if params.Sync<>INVALID_HANDLE_VALUE then
begin
for i:=low(Threads) to High(Threads) do Threads[i]:= CreateThread(nil,0,@ThreadProc,@params,0,tid);
end;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
SetEvent(params.Sync);
while params.ThreadCount<length(Threads) do CheckSynchronize;
Showmessage('Threads None');
end;
Сергей М. (2007-08-10 14:09:00) [8]
> когда код пишите, тоже пыжитесь?
Код, в котором я хотя бы в какой-то мере не уверен, - да, "пыжусь" и пишу, пишу и "пыжусь" ...)
Но НЕ для выноса в кач-ве публичного жупела) ... Жупела по поводу и без повода) ..
> много чего существует
Вот и нарисуй одно из них)
ЗАЧЕМ провоцировать весьма непосвещенного Автора хотя бы на "CreateThread", если он грозит ему еще и бОльшими неприятностями с учетом его знаний ?
Репу-то почеши)..
oxffff (2007-08-10 14:02:00) [9]
> Чем дальше, тем речь твоя становится менее разборчивой.
Да все просто мой пример вызывает в deadlock. Поэтому и пришлось ставить 5000. Причина вызов Synchronize.
Я почему был уверен, что Synchronize ставит в очередь и продолжает работу.
Это моя вина
Ждем исправлений.
> Нужно обязательно пыжиться, демонстрируя логику "в особо
> извращенной форме" ?)
А вы что когда код пишите, тоже пыжитесь?
Я нет. Думаю и вы тоже.
>И кроме lock и invalidate cash lines разве не существуют способы прямо в >коде Делфи заставить ЦП обновить тот или иной кэш БЕЗ правки кода >TThread ?
Да много чего существует.
Сергей М. (2007-08-10 13:49:00) [10]
> Называется она deadLock. :)
А объяснить Автору, при каких условиях может возникнуть этот самый "дэдлок", - оно ниже твоего "достоинства" ?
Нужно обязательно пыжиться, демонстрируя логику "в особо извращенной форме" ?)
И кроме lockи invalidate cash linesразве не существуют способы прямо в коде Делфизаставить ЦП обновить тот или иной кэш БЕЗ правки кода TThread ?
Существуют)
На том и желаю тебе сосредоточиться, во благо и Автора и твоего "доброго имени")
Leonid Troyanovsky (2007-08-10 13:44:00) [11]
> oxffff © (10.08.07 13:32) [30]
> > Но, это ж не воспрепятствовало использованию, например,
> > Synchronize?
> Cвязь между ними есть, но она другая. Называется она deadLock.
Чем дальше, тем речь твоя становится менее разборчивой.
Связь между кем? Хендлы & dwMilliseconds?
Synchronize & Handle ?
И причем здесь deadlock.
--
Regards, LVT.
oxffff (2007-08-10 13:32:00) [12]
> Но, это ж не воспрепятствовало использованию, например,
> Synchronize?
Cвязь между ними есть, но она другая. Называется она deadLock. :)
oxffff (2007-08-10 13:13:00) [13]
> Чего ради ты пыжишься ?)
Я? С чего вы взяли?
По причине того, что FTerminated является Shared и execute по логике должен проверять ее. То и делать надо все c lock префиксом, либо с invalidate cash lines.
Посмотрите MSDN, хороший пример.
Leonid Troyanovsky (2007-08-10 13:12:00) [14]
> oxffff © (10.08.07 13:00) [24]
> > надо пользовать TThread instead CreateThread
> Про хваленый Tthread читать [4]
Но, это ж не воспрепятствовало использованию, например, Synchronize?
Чем, скажем, TThread.Handle хужее?
Да и речь там шла про FTerminated, ну и надо было вопрошаещему
рассказать как к нему применять InterlockedCompareExchange,
а не умничать ;)
> Вы внимательно читаете MSDN?
Стараюсь.
Только, связи между одним из хендлов и dwMilliseconds не заметил.
--
Regards, LVT.
oxffff (2007-08-10 13:07:00) [15]
> Но не смотря на все это я не стал уважать меньше.
Но не смотря на все это я не стал уважать вас меньше.
Сергей М. (2007-08-10 13:07:00) [16]
> oxffff
Чего ради ты пыжишься ?)
Рано или поздно модифицирующий это самое "FTerminated" процеccор сбросит и обновит кэш, и потоку, который выполняется там, остается только ждать (сколько потребуется), когда другой процессор, на котором выполняется интересующий поток, обновит свой кэш и обнаружит взведение этого флага.
В чем проблема ?
К чему все эти твои алгоритмические "изыски"-выкрутасы, если они в большинстве случаев нафих не нужны ?
oxffff (2007-08-10 13:06:00) [17]
> Сергей М. © (10.08.07 12:58) [23]
>
> > Leonid Troyanovsky © (10.08.07 12:49) [21]
>
>
> oxffff(с) на протяжении последнего времени просто пыжит
> пуп в надежде нарисоваться глубочайшим в истории Мастаков
> исследователем геморроя, подаренного Борлангдом всем пользователям
> его шедевров)
>
> Вот и все дела)
Я в отличие от вас могу признать, что не могу знать все (да да я про DWORD alignment). Вы же свои ошибки не признаете, вместе с А.П.
Предпочитая отмолчаться.
Но не смотря на все это я не стал уважать меньше.
oxffff (2007-08-10 13:00:00) [18]
> Незнающим как синхронизироваться с главным потоком
> надо пользовать TThread instead CreateThread
Про хваленый Tthread читать [4]
> Cначала у нас была вечность. Так что ж смутило?
> Ремарка в msdn относится не к этому параметру.
Вы внимательно читаете MSDN?
lpHandles
[in] Pointer to an array of object handles.
......
If one of these handles is closed while the wait is still pending, the function's behavior is undefined.
Сергей М. (2007-08-10 12:58:00) [19]
> Leonid Troyanovsky © (10.08.07 12:49) [21]
oxffff(с) на протяжении последнего времени просто пыжит пуп в надежде нарисоваться глубочайшим в истории Мастаков исследователем геморроя, подаренного Борлангдом всем пользователям его шедевров)
Вот и все дела)
Leonid Troyanovsky (2007-08-10 12:52:00) [20]
> MetalFan © (10.08.07 12:45) [20]
> может стоит BeginThread вместо CreateThread использовать?
Не можно, а нужно.
Стоит так поставить.
--
Regards, LVT.