Форум: "Основная";
Текущий архив: 2004.05.16;
Скачать: [xml.tar.bz2];
ВнизПотоки в "Дельфевых" библиотеках Найти похожие ветки
← →
YuRock © (2004-04-28 14:33) [0]Доброго всем дня! Вот нужно мне написать плугин, который работает с железякой ч-з Com-порт.
Вначале я написал экзешник (для тестов, да и отлаживать exe удобнее, чем dll) - в потоке опрашиваю Com-порт, ну и, кое-что делаю. Когда полностью отладился, все заработало - решил перенести функциональность в dll.
И тут началось самое интересное! В dll я сделал отдельный модуль, который выглядит примерно так:
unit Point;
interface
implementation
uses
Windows, Classes;
type
TMyThread = class(TThread)
public
procedure Execute; override;
end;
var
Thread: TMyThread;
procedure TMyThread.Execute;
begin
MessageBox(0, "1", "", 0);
end;
initialization
Thread := TMyThread.Create(False);
if True then // здесь у меня своя проверка на то, что "все нормально проинициализировалось"
ExitCode := 1; // если не "все нормально проинициализировалось" - сделать так, чтобы LoadLibrary вернула 0
finalization
Thread.Free;
end.
Так вот, до TMyThread.Execute даже не доходит! Ну это ладно, еще можно понять... Но зачем же тогда намертво виснуть на "Thread.Free"?!!
Если конкретнее, виснет на выполнении WaitFor, который вызывается в TThread.Destroy. Что посоветуете, мастера? У меня в библиотеке не один и не два потока, и все они инициализируются, и на Free все вешаются.
Кстати, мастера, объясните, как работает параметр CreateSuspended в TThread.Create, если в BeginThread все равно передается CREATE_SUSPENDED, даже если CreateSuspended=False:
FSuspended := CreateSuspended;
FCreateSuspended := CreateSuspended;
FHandle := BeginThread(nil, 0, @ThreadProc, Pointer(Self), CREATE_SUSPENDED, FThreadID);
if FHandle = 0 then
raise EThread.CreateResFmt(@SThreadCreateError, [SysErrorMessage(GetLastError)]);
А то что-то не понятно мне. Спасибо.
← →
Digitman © (2004-04-28 14:51) [1]крайне некорректно, а в ряде случаев и недопустимо манипулировать созданием/разрушением потоков в секциях инициализации/финализации модулей библиотеки
кр.того, если уж ты стартовал поток в разделе иниц-ции, какое право ты имеешь возвращать ExitCode = 1 ? Ведь поток уже стартован, а ты извещаешь систему об ошибке инициализации ! До раздела финализации вообще дело не дойдет, поскольку этот раздел вызывается при выгрузке библиотеки, но она системой не загружена даже, ты сам этому посодействовал, вернув ExitCode = 1
← →
YuRock © (2004-04-28 14:59) [2]> До раздела финализации вообще дело не дойдет
Да нет, доходит как раз (я и в отладке смотрел, и в файл выводил). Но даже так - тоже вешается (вообще без finalization):
initialization
Thread := TMyThread.Create(False);
if True then begin
Thread.Free;
ExitCode := 1; // чтобы LoadLibrary вернула 0
end;
А как быть? У меня инициализация очень большая! Идет секунд 15. Куча чего делается. Что, отдельную ф-цию делать? Тогда прийдется весь проэкт перелапачивать и все плугины (уже написанные), и работу с ними менять!
← →
YuRock © (2004-04-28 15:06) [3]> Digitman © (28.04.04 14:51) [1]
> крайне некорректно, а в ряде случаев и недопустимо манипулировать созданием/разрушением потоков в секциях инициализации/финализации модулей библиотеки
Объясните, пожалуйста, причины этого Вашего высказывания.
← →
Digitman © (2004-04-28 15:06) [4]
> Что, отдельную ф-цию делать? Тогда прийдется весь проэкт
> перелапачивать
а это уже твои проблемы ...
еще раз повторяю - нельзя этого делать в иниц-ции/финал-ции !
← →
YuRock © (2004-04-28 15:08) [5]> еще раз повторяю - нельзя этого делать в иниц-ции/финал-ции !
Еще раз прошу: можете объяснить, почему?
← →
YuRock © (2004-04-28 15:17) [6]И еще: никто не может дать ответ на второй вопрос (как работает (используется) параметр CreateSuspended в TThread.Create), если он при создании потока не используется:
constructor TThread.Create(CreateSuspended: Boolean);
begin
inherited Create;
AddThread;
FSuspended := CreateSuspended;
FCreateSuspended := CreateSuspended;
FHandle := BeginThread(nil, 0, @ThreadProc, Pointer(Self), CREATE_SUSPENDED, FThreadID);
if FHandle = 0 then
raise EThread.CreateResFmt(@SThreadCreateError, [SysErrorMessage(GetLastError)]);
end;
?
← →
Digitman © (2004-04-28 15:28) [7]
> YuRock © (28.04.04 15:17) [6]
по [6] комментариев не имею - пользую исклн-о Д5 ... в ней все ясно и корректно
> почему?
как минимум потому что я понятия не имею. что у тебя творится в Execute()
← →
panov © (2004-04-28 15:45) [8]>YuRock © (28.04.04 15:17) [6]
Если уж идти по цепочке, то дальше.
function BeginThread(SecurityAttributes: Pointer; StackSize: LongWord;
ThreadFunc: TThreadFunc; Parameter: Pointer; CreationFlags: LongWord;
var ThreadId: LongWord): Integer;
var
P: PThreadRec;
begin
New(P);
P.Func := ThreadFunc;
P.Parameter := Parameter;
IsMultiThread := TRUE;
Result := CreateThread(SecurityAttributes, StackSize, @ThreadWrapper, P,
CreationFlags, ThreadID);
end;
← →
YuRock © (2004-04-28 15:53) [9]> Digitman © (28.04.04 15:28) [7]
> как минимум потому что я понятия не имею. что у тебя творится в Execute()
Я же написал пример!!! В Execute() у меня творится "ничего" (в данном примере - вызо ф-ции MessageBox()) - и все!!! Этого достаточно! До нее не доходит! Почему?
> panov © (28.04.04 15:45) [8]
> Если уж идти по цепочке, то дальше.
Ну и что? При чем здесь реализация BeginThread? В CreationFlags ф-ции CreateThread же как раз всегда и передается CREATE_SUSPENDED, который передается в BeginThread, который вызывается в TThread.Create!
← →
YuRock © (2004-04-28 15:56) [10]>Digitman
>panov
>...
Извините, что надоел вопросами. Просто не люблю использовать то, что работает (в данном случае - не работает) непонятно как и почему.
← →
Digitman © (2004-04-28 16:02) [11]
> YuRock © (28.04.04 15:56) [10]
а я. знаешь ли, не люблю пустой треп на протяжении 10-ти постов без обсуждения реально представленногго проблемного кода потока
← →
vl_chel © (2004-04-28 16:13) [12]>>как работает параметр CreateSuspended в TThread.Create,
Если True то создает приостановленный поток
Есть подозрение что твоя инициализация прибивает работоспособность потока, возможно надо поток создавать приостановленным, а затем если прошла успешно запускать
← →
YuRock © (2004-04-28 16:17) [13]> Digitman © (28.04.04 16:02) [11]
Еще раз повторяю (з-й раз уже, однако, для нелюбителей пустого трепа). Вот проблемный код потока:
procedure TMyThread.Execute;
begin
MessageBox(0, "1", "", 0);
end;
или
procedure TMyThread.Execute;
begin
end;
или ЛЮБОЙ другой!!!
← →
YuRock © (2004-04-28 16:23) [14]> vl_chel © (28.04.04 16:13) [12]
Да что никак ни кто не поймет! У меня поток не то, что создается приостановленным, а вообще стоячим и нерабочим в любом случае!
Для особо умных, кто не верит - можете взять представленный мною пример - его достаточно, чтобы увидеть неработу. Сам пример компилится с первого раза. Осталось только вставить его в файл и сбилдить dll. Да еще LoadLibrary вызвать где-нибудь.
← →
Digitman © (2004-04-28 16:27) [15]в на момент загрузки и инициализации системой PE-модуля в АП хост-процесса происходит блокировка PEB процесса ... создаваемый же тобой поток требует от системы создания TEB+TIB, в ходе чего происходит обращение к крит.секции в PEB, которая на этот момент занята ... отсюда и "вис"
еще раз повторяю - убирай из иниц-ции/финал-ции работу с потоками, выноси ее на уровень эксп.ф-ций
← →
panov © (2004-04-28 16:30) [16]>YuRock © (28.04.04 16:17) [13]
Если уж с такими претензиями, то стоит пройти более внимательно по цепочке вызовов, тогда вопросов не возникнет.
← →
Digitman © (2004-04-28 16:31) [17]
> YuRock © (28.04.04 16:23) [14]
> Для особо умных
"особо умные" задают этот вопрос в WinApi и не тычут при этом якобы безапелляционным аргументом, мол, в ЕХЕ у меня все Ок, так какого же хрена в ДЛЛ с тем же самым проблемы..
"особо умные" перед тем как задать вопрос прилагают все возможные усилия для постижения сист.механизма загрузки РЕ-модулей
← →
panov © (2004-04-28 16:33) [18]По поводу ошибки при инициализации библиотеки.
Никогда не возвращай ошибку при инициализации библиотеки из нее.
Это глюк реализации DLL в Delphi.
Потоки прекрасно работают из библиотек.
Про секцию intialization тебе уже сказали.
← →
Digitman © (2004-04-28 16:37) [19]
> panov © (28.04.04 16:33) [18]
> Никогда не возвращай ошибку при инициализации библиотеки
> из нее.
> Это глюк реализации DLL в Delphi.
ну здесь ты, наверно, неправ
Halt(1) никому и ни при каких условиях не запрещено делать, разве что в хук-библиотеках - там с этим "темный лес"
а вот о том, что перед halt(1) следовало бы освободить все занятые на этот момент ресурсы - это да, на этом конечно же следует заострить внимание ...
под ресурсами в дан.случае не подразумеваются трэды
← →
panov © (2004-04-28 16:40) [20]>Digitman © (28.04.04 16:37) [19]
Не от тебя ли была ветка про возврат ExitCode<>0 из библиотеки при ее инициализации?
← →
YuRock © (2004-04-28 16:43) [21]> Digitman
Я сказал, что в Exe работает лишь для того, чтобы у отвечающих не возникало вопроса о правильности кода потока (который Вы, как ни странно, задавали 2 раза), а ни как аргумент. И "какого хрена" я никогда не говорил. Я лишь спрашивал совета: как быть?
И всеже спасибо Вам.
> panov
> Никогда не возвращай ошибку при инициализации библиотеки из нее. Это глюк реализации DLL в Delphi.
Почему? Я использовал уже это. И не раз. Может, в старых версиях и глючило, но в D6 - пока проблем не было.
А мою проблему в [15] довольно понятно объяснил Digitman © - она не в Delphi заключается, так как с API-шным CreateThread было то же самое - я проверял.
← →
vl_chel © (2004-04-28 16:55) [22]YuRock © (28.04.04 16:23) [14]
Согласно вашему созданию Thread := TMyThread.Create(False); не верю - он сразу начинает работу !!
← →
YuRock © (2004-04-28 17:02) [23]> vl_chel © (28.04.04 16:55) [22]
1. Внимание неверующих я уже неоднократно обращал на предоставленный пример.
2. Проблема уже решена (понятна) - тема закрыта.
← →
Digitman © (2004-04-28 17:10) [24]
> panov © (28.04.04 16:40) [20]
от меня.
и речь там явно шла о хук-ДЛЛ
> vl_chel © (28.04.04 16:55) [22]
> не верю - он сразу начинает работу !!
нет, не сразу ... старту потока предшествует весьма сложный системный механизм модификации сист.структур в АП процесса ... и этот механизм тесно связан с крит.секциями
← →
vl_chel © (2004-04-28 17:28) [25]>>Digitman © (28.04.04 17:10) [24]
это знаю да но 15 сек ??
думаю вопрос не с системой
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.05.16;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.033 c