Текущий архив: 2006.10.08;
Скачать: CL | DM;
ВнизОстановка потока Найти похожие ветки
← →
Destroyer © (2006-08-26 21:28) [0]Задача выполняется в потоке. По нажатию кнопки на форме надо остановить выполнение потока. Проверять флаг постоянно на отключение - не подходит. Нужно что-то типа TimerThread.Destroy.
Делаю так:
protected
procedure Execute; override;
public
constructor Create(FPath: String; Fflag: boolean; RProcType:string; FExt:string);
constructor Destroy;
end;
...
constructor TimerThread.Destroy;
begin
exit;
end;
Но так, выдается ошибка неверный дескриптор.
Как правильно мгновенно остановить поток?
← →
Ketmar © (2006-08-26 21:29) [1]правильно -- проверять флаг.
← →
DVM © (2006-08-26 21:34) [2]
> Проверять флаг постоянно на отключение - не подходит
именно это самый быстрый и корректный путь.
> Как правильно мгновенно остановить поток?
Мгновенно, но не всегда правильно TerminateThread()
← →
Fay © (2006-08-26 22:18) [3]> constructor Create(FPath: String; Fflag: boolean; RProcType:string; FExt:string);
> constructor Destroy;
Это просто бред
← →
Ketmar © (2006-08-26 22:20) [4]> [3] Fay © (26.08.06 22:18)
вах! а я и не заметил. %-)
← →
Destroyer © (2006-08-26 23:06) [5]BOOL TerminateThread(
HANDLE hThread, // handle to the thread
DWORD dwExitCode // exit code for the thread
);
Где взять хэндл потока?
Поток создается так:
TimerThread.Create(dir1,false,"Param1",Ext);
← →
Чапаев носками хакера (2006-08-26 23:30) [6]> Где взять хэндл потока?
OpenThread(). Подробности в справке.
← →
Destroyer © (2006-08-27 01:02) [7]Извините, конечно, но все что нашось в справке - OpenThread() that takes a thread ID and returns a thread handle. А где ID взфть?
Также говорится, что хэндл получается при создании потока.
CreateThread() API is used to create threads.
Но у меня поток создается способом см. выше. Может из него как-то хэндл взять?
← →
Германн © (2006-08-27 01:46) [8]
> Но у меня поток создается способом см. выше. Может из него
> как-то хэндл взять?
А что тогда есть
> TimerThread
?
Я такого не знаю. Чей он потомок?
← →
Чапаев носками хакера (2006-08-27 08:54) [9]> Извините, конечно, но все что нашось в справке - OpenThread()
> that takes a thread ID and returns a thread handle. А где
> ID взфть?
Если поток твой, тебе лучше знать, какой у него TID. Если чужой, смотри справку по CreateToolhelp32Snapshot(), а дальше по ссылкам.
← →
begin...end © (2006-08-27 09:02) [10]> Чапаев носками хакера (26.08.06 23:30) [6]
TThread.Handle. Подробности в справке.
← →
Destroyer © (2006-08-27 14:32) [11]Германн,
type
TimerThread = class(TThread)
begin...end,
В справке есть.
Indicates the thread"s handle (Windows only).
Delphi syntax:
property Handle: THandle;
Видимо, то что нужно.
Но компилятор не принимает, ошибка: Method identifier expected.
← →
y-soft © (2006-08-27 22:06) [12]>Destroyer © (26.08.06 23:06) [5]
Не используйте TerminateThread, это чревато многими неприятностями и используется в самых крайних аварийных случаях
Самое правильное и простое в Вашем случае - установить при создании TTimerThread
FreeOnTerminate := True и периодически проверять флаг. Когда функция потока обнаружит, что флаг установлен - просто выходить из функции потока. Тогда и хендл потока Вам не понадобится
Другого корректного (а тем более "мгновенного" способа) в общем случае просто не существует (хотя могут и быть варианты в зависимости от того, чем конкретно занимается поток. Например, можно мгновенно отменить все операции ввода/вывода для файлового устройства, закрыв все открытые хендлы этого устройства)
← →
DVM © (2006-08-27 22:08) [13]
> FreeOnTerminate := True
Крайне глюконосная фича.
← →
y-soft © (2006-08-27 22:12) [14]>DVM © (27.08.06 22:08) [13]
TThread в Delphi вообще написан довольно криво :(
Но в большинстве случаев все работает
← →
Ketmar © (2006-08-27 22:15) [15]поркзаная цитата из генофонда:
function ThreadProc(Thread: TThread): Integer;
var
FreeThread: Boolean;
begin
try
if not Thread.Terminated then
try
Thread.Execute;
except
Thread.FFatalException := AcquireExceptionObject;
end;
finally
FreeThread := Thread.FFreeOnTerminate;
Result := Thread.FReturnValue;
Thread.DoTerminate;
Thread.FFinished := True;
SignalSyncEvent;
if FreeThread then Thread.Free;
EndThread(Result);
end;
end;
если писать корректно и не совершать страшного в OnTerminate(), то никаких глюков не вижу.
← →
y-soft © (2006-08-27 22:18) [16]>DVM © (27.08.06 22:08) [13]
FreeOnTerminate предполагает, что судьба потока после завершения неинтересна - завершился и самоуничтожился. Для того, чтобы избежать глюков следует отловить завершение потока (например, с помощью WaitForXXX) и обнулить указатели на него
← →
DVM © (2006-08-27 22:23) [17]
> Для того, чтобы избежать глюков следует отловить завершение
> потока
Я бы советовал в любом случае это делать.
← →
y-soft © (2006-08-27 22:25) [18]>DVM © (27.08.06 22:23) [17]
Я бы советовал в любом случае это делать
Конечно, если есть хотя бы один указатель на него и существует вероятность, что к нему возможно обращение
← →
Пусик © (2006-08-27 22:27) [19]
> DVM © (27.08.06 22:08) [13]
>
> > FreeOnTerminate := True
>
> Крайне глюконосная фича.
Это еще почему?
Вряд ли она ВООБЩЕ хоть чуть-чуть глюконосная.
> y-soft © (27.08.06 22:12) [14]
>
> TThread в Delphi вообще написан довольно криво :(
А что в нем кривого особо?
← →
DVM © (2006-08-27 22:29) [20]
> Вряд ли она ВООБЩЕ хоть чуть-чуть глюконосная.
Глюки не в ней, а в неправильном ее использовании. Иногда даже и не подумаешь, что проблемы именно в ней.
← →
y-soft © (2006-08-27 22:31) [21]>Пусик © (27.08.06 22:27) [19]
А что в нем кривого особо?
ОСОБО кривого нет. Есть отдельные недодуманности. Например метод Synchronize - основная причина тормозов в многопоточных программах начинающих :)
Вообще, начиная с Windows 2000 появилась прекрасная альтернатива TThread в большинстве случаев - системный пул потоков
← →
Пусик © (2006-08-27 22:34) [22]
> y-soft © (27.08.06 22:31) [21]
> >Пусик © (27.08.06 22:27) [19]
>
> А что в нем кривого особо?
>
> ОСОБО кривого нет. Есть отдельные недодуманности. Например
> метод Synchronize - основная причина тормозов в многопоточных
> программах начинающих :)
>
> Вообще, начиная с Windows 2000 появилась прекрасная альтернатива
> TThread в большинстве случаев - системный пул потоков
Да, альтернатива есть, но как раз начинающим использование пула потоков рекомендовать нельзя слишком сложно для использования. Да и вряд ли у начинающих возникнут задачи, требующие подобного решения.
← →
Ketmar © (2006-08-27 22:36) [23]> [21] y-soft © (27.08.06 22:31)
интересно, каким боком Synchronuze() относится к реализации TThread? это, вообще-то, проблема VCL.
← →
y-soft © (2006-08-27 22:37) [24]>Пусик © (27.08.06 22:34) [22]
...но как раз начинающим использование пула потоков рекомендовать нельзя слишком сложно для использования
IMHO намного проще получается, чем с TThread, но программирование действительно сложное занятие, особенно профессиональное :)
← →
DVM © (2006-08-27 22:40) [25]
> интересно, каким боком Synchronuze() относится к реализации
> TThread? это, вообще-то, проблема VCL.
A TThread не из VCL что ли?
← →
y-soft © (2006-08-27 22:40) [26]>Ketmar © (27.08.06 22:36) [23]
Проблема в том, что не предусмотрено метода Asynchronize :)
← →
Пусик © (2006-08-27 22:46) [27]
> y-soft © (27.08.06 22:40) [26]
> >Ketmar © (27.08.06 22:36) [23]
>
> Проблема в том, что не предусмотрено метода Asynchronize
> :)
Ну как раз реализация асинхронной синхронизации не представляет сложности;)
← →
y-soft © (2006-08-27 22:59) [28]>Пусик © (27.08.06 22:46) [27]
Безопасная реализация достаточна сложна. Начинающему явно не по зубам
Хотя... Можно, например, сделать так:
http://y-soft.comsignal.ru/Delphi/ThreadX_pas.html (просьба сильно не пинать) :)
← →
Ketmar © (2006-08-27 23:03) [29]> [27] Пусик © (27.08.06 22:46)
> асинхронной синхронизации
не надо так шутить на ночь глядя. %-)
← →
Slym © (2006-08-28 04:43) [30]Мой пинок в бочину TThread - Terminate - не виртуальный, как хочется в него чегонибудь добавить, например обрыв синхронных вызовов
← →
Fay © (2006-08-28 04:51) [31]2 Slym © (28.08.06 4:43) [30]
> Terminate - не виртуальный, как хочется в него
> чегонибудь добавить, например обрыв синхронных вызовов
Коран не запрещает завернуть Terminate в свой метод
← →
Ketmar © (2006-08-28 05:00) [32]равно как сделать обработчик события OnTerminate().
← →
Slym © (2006-08-28 10:14) [33]Fay © (28.08.06 4:51) [31]
Коран не запрещает завернуть Terminate в свой метод
А дальнейшее приведение типа TThread(Thread).Terminate? или сунуть руки в генофонд?
← →
Slym © (2006-08-28 10:18) [34]Ketmar © (28.08.06 5:00) [32]
обработчик события OnTerminate()
сработает после выхода из процедуры потока...
прерывать синхронный вызов в OnTerminate бессмысленно, т.к. он уже отвалился сам. вот еслиб был OnBeforeTerminate
← →
Ketmar © (2006-08-28 10:43) [35]> [34] Slym © (28.08.06 10:18)
> сработает после выхода из процедуры потока...
и в чём проблема, если всё равно создаётся класс-потомок? нужные переменные -- в поля.
> прерывать синхронный вызов
это что такое? поподробней можно?
← →
Ketmar © (2006-08-28 10:43) [36]> [33] Slym © (28.08.06 10:14)
"завернуть" и "перекрыть" -- вещи разные.
← →
BiN © (2006-08-28 10:47) [37]Любые высказывания в сторону кажущейся кривости реализации TThread необоснованны и посему - бред.
имо.
← →
isasa © (2006-08-28 10:53) [38]:)
В общем, отсюда вывод, юзаем CreateThread (для фанатов BeginThread).
← →
y-soft © (2006-08-28 10:55) [39]>BiN © (28.08.06 10:47) [37]
Несколько безаппеляционно сказано. IMHO, конечно :)
← →
isasa © (2006-08-28 10:58) [40]Slym © (28.08.06 04:43) [30]
.... как хочется в него чегонибудь добавить, например обрыв синхронных вызовов
Для таких случаев даден флаг Terminated, что-бы нормально разрулить логику внутри метода Execute. Конечно, если сносить поток шашкой (TerminateThread), то тогда все равно. :)
Страницы: 1 2 вся ветка
Текущий архив: 2006.10.08;
Скачать: CL | DM;
Память: 0.55 MB
Время: 0.045 c