Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
1-65465
Ish1
2003-10-09 10:31
2003.10.20
Запуск программ


1-65538
TUser
2003-10-08 09:36
2003.10.20
header


3-65354
elle
2003-09-29 14:06
2003.10.20
фильтрация записей в TClientDataSet


3-65379
GydruS
2003-09-25 02:32
2003.10.20
Здравствуйте! Тут мега проблема! F1! F1!


1-65467
DimChan
2003-10-09 09:13
2003.10.20
Ввод числа денежного эквивалента





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский