Форум: "Основная";
Текущий архив: 2003.10.20;
Скачать: [xml.tar.bz2];
ВнизПроблем при использовнии потоков. Найти похожие ветки
← →
Владислав (2003-10-07 13:22) [40]Он не уничтожиться, пока не выйдет из процедуры Synchronize.
А он из нее не выйдет, пока не закончиться CheckSynchronize.
Там критическая секция стоит.
← →
Владислав (2003-10-07 13:25) [41]Даже не так. Если в WakeMainThread(Self); произойдет исключение, и оно не будет обработано, то и объект TThread уничтожен не будет.
← →
Digitman (2003-10-07 13:27) [42]
> Владислав
чегой-то вдруг ?)
а на кой шут мне тогда нужна эта VCL, если я не могу воспользоваться в общем-то неплохим классом TThread, избавляющим меня от массы рутинной работы ?)
не-е-е) ... ты не прав здесь !
просто для обхода этих неприятностей следует предпринять некие непредусмотренные Борландом (правда, не такие уж тривиальные) действия ... скажем, перехватить в хост-процессе любой WinAPI-вызов или оконное сообщение, и в обработчике перехвата :
- найти Id осн.код.потока процесса;
- сравнить с CurrentThreadId;
- если равны, то создать окно, диспетчеру сообщений которого впоследствии можно будет посылать тем или иным образом из прочих потоков сообщение с указанием выполнить такую-то процедуру/метод ... т.е. далее - по прямой аналогии с реализацией в Д5 ... разумеется, речь не идет о кросс-платформенности решения
← →
Владислав (2003-10-07 13:37) [43]> Digitman © (07.10.03 13:27) [42]
Я, конечно же, пошутил.
Я бы поступил проще. Установил бы хук на сообщения главного окна приложения. В нем бы вызывал CheckSyncronize. А на WaikMainThread. Посылал бы главному окну приложения какое-нибудь сообщение. Хотя, простота, дело субъективное ;)
← →
Verg (2003-10-07 13:43) [44]
> Даже не так. Если в WakeMainThread(Self); произойдет исключение,
> и оно не будет обработано, то и объект TThread уничтожен
> не будет.
Да нет. С чего бы это? Будет уничтожен. Да еще как.
На ка, запусти:
program TestT;
uses
Windows,
Classes, Sysutils;
type
HostObject = class
procedure Dosome(Sender: TObject);
end;
MThread = class(TThread)
public
constructor Create;
procedure Execute; override;
procedure SomeMethod;
end;
procedure HostObject.Dosome(Sender: TObject);
begin
Abort;
end;
procedure MThread.SomeMethod;
begin
end;
constructor MThread.Create;
begin
FreeOnTerminate:=true;
inherited Create(false);
end;
procedure MThread.Execute;
begin
Synchronize(SomeMethod);
end;
Var Host : HostObject;
Mt : MThread;
begin
Host := HostObject.Create;
Classes.WakeMainThread:=Host.Dosome;
Mt:=MThread.Create;
while true do
begin
CheckSynchronize;
Sleep(500);
end;
end.
← →
Verg (2003-10-07 13:45) [45]Там Abort можешь на CheckSinchronize заменить. Сути это не изменит.
← →
Digitman (2003-10-07 13:48) [46]
> Владислав
> сообщения главного окна приложения
окно никаких сообщений не посылает, они (сообщения) ему адресованы ... корректней было бы сказать "сообщения главному окну приложения"
тогда тебе вопросы ч.н. "на засыпку" :
- откуда ты знаешь, "главное" то или иное окно или "не главное" ? кто тебе об этом скажет, кроме разработчика non-Delphi-приложения ?
- а если приложение консольное и не создает явно никаких окон ? что будешь считать "главным" ?
← →
Verg (2003-10-07 13:54) [47]
> Digitman ©
А скажи: на кой нам в DLL синхронизироваться с тем, кто вызвал некую процедуру из DLL и с кем мы ничего общего, кроме параметров этой процедуры не имеем?
← →
Владислав (2003-10-07 13:59) [48]> Digitman © (07.10.03 13:48) [46]
"сообщения главному окну приложения"
Согласен. Некорректно выразился.
"тогда тебе вопросы ч.н. "на засыпку" "
Вопрос весь в том, я пишу библиотеку для какого то приложения, или разработчик собирается использовать мою библиотеку для своего приложения.
Для первого случая я вариант сказал. Winspertor Spy мне поможет с окном.
Для второго случая я предложил бы разработчику способ управлять потоками созданными в библиотеке. И написал бы в хелпе, как этим способом пользоваться. Это даже проще, чем первый вариант.
> Verg © (07.10.03 13:43) [44]
Это не показатель. Необработанное исключение внутри Execute так же приведет к AV. Так что, Борланд и там напортачило? Я думаю, это вполне корректный подход.
← →
Verg (2003-10-07 14:05) [49]
> Это не показатель. Необработанное исключение внутри Execute
> так же приведет к AV.
Да нет, ничего подобного.
Если произошло необработанное исключение в execute, то поток завершиться, а само объект исключение будет лежать у него в FatalException. Хотя если FreeOnTerminate=true, то и этот объект никому не нужен.
try
if not Thread.Terminated then
try
Thread.Execute;
except
Thread.FFatalException := AcquireExceptionObject;
end;
finally
FreeThread := Thread.FFreeOnTerminate;
Result := Thread.FReturnValue;
Thread.FFinished := True;
Thread.DoTerminate;
if FreeThread then Thread.Free;
.....
← →
Verg (2003-10-07 14:15) [50]
> Так что, Борланд и там напортачило?
Не знаю кто там что напортачил. Мое дело - предупредить, что вот такой подводный камень там есть.
Что вот это,
In a non-GUI application, you must call CheckSynchronize if you use the Synchronize method of TThread. To do this, set the WakeMainThread variable to a procedure that calls CheckSynchronize.
мягко говоря, неточность.
И что Synchronize с D6 - это со-о-овсем не тот Synchronize, что был раньше.
← →
Digitman (2003-10-07 14:21) [51]
> Verg © (07.10.03 13:54) [47]
> А скажи: на кой нам в DLL синхронизироваться с тем, кто
> вызвал некую процедуру из DLL и с кем мы ничего общего,
> кроме параметров этой процедуры не имеем?
а и не с ним вовсе (с тем, кто вызвал нас) нам синхронизироваться нужно !
представь себе задачу : осн.поток хост-процесса занял некий ресурс в полной уверенности, что владеет им монопольно.
Мы не имеем никакого права асинхронно "трогать" этот ресурс , это чревато крахом процесса. Но скомандовать осн.потоку выполнить некие действия над ресурсом "от нашего имени" мы вправе
← →
Владислав (2003-10-07 14:25) [52]> Verg © (07.10.03 14:05) [49]
Да, согласен. Мое сообщение Владислав © (07.10.03 13:59) [48] не к тому месту было :)
← →
Verg (2003-10-07 14:33) [53]
> Мы не имеем никакого права асинхронно "трогать" этот ресурс
> , это чревато крахом процесса.
Этот ресурс должен быть защищен.
Ну в простейшем случае - критическая секция.
> Но скомандовать осн.потоку выполнить некие действия над
> ресурсом "от нашего имени" мы вправе
Тогда ОКП должен же дать какой-то механизм доступа "к себе". Вот там, в этом его шлюзе он и должен разруливать свой ресурс, продпологая, конечно, что в этот шлюз может заходить и другой контекст.
← →
Digitman (2003-10-07 15:19) [54]
> Verg
> Этот ресурс должен быть защищен
он и защищен хост процессом ... возможно ... но о механизме этой защиты наша ДЛЛ ничего не знает. поэтому вынуждена синхронизироваться с потоком, занявшим ресурс
> Тогда ОКП должен же дать какой-то механизм доступа "к себе".
ничего он не должен) ... он знать ничего не знает о том, что требуется логике, реализованной во ДЛЛ ... он просто вызвал ф-цию и ожидает рез-та ее выполнения в соответствии со спецификацией производителя
← →
Verg (2003-10-07 15:44) [55]Я думаю, что надо будет прибегнуть к тому же методу синхронизации, что и раньше, только самостоятельно "вручную".
Через такое же теневое окошко, которое будет создаваться где-либо в контексте вызывающего потока (да хоть в той же ф-ции или в DLLProc/DLL_PROCESS_ATTACH).
← →
Digitman (2003-10-07 15:55) [56]
> Verg
эт ты кому ? и по какому поводу ?
← →
Verg (2003-10-07 16:01) [57]
> Digitman © (07.10.03 15:55) [56]
>
> > Verg
>
>
> эт ты кому ? и по какому поводу ?
Тебе.
По поводу как из потока рожденного в фун-ции DLL синхронизироваться с потоком вызвавшим эту ф-цию.
Страницы: 1 2 вся ветка
Форум: "Основная";
Текущий архив: 2003.10.20;
Скачать: [xml.tar.bz2];
Память: 0.56 MB
Время: 0.008 c