Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2006.10.08;
Скачать: [xml.tar.bz2];

Вниз

Остановка потока   Найти похожие ветки 

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.55 MB
Время: 0.039 c
15-1158643332
Ega23
2006-09-19 09:22
2006.10.08
С Днём рождения! 19 сентября


15-1158557887
Ega23
2006-09-18 09:38
2006.10.08
С Днём рождения! 18 сентября


2-1158511777
POP
2006-09-17 20:49
2006.10.08
Асинхронное IO чтение/запись в порт.


2-1158359832
Juri
2006-09-16 02:37
2006.10.08
Фильтровать базу данных по куску слова


2-1158689056
KEBZ
2006-09-19 22:04
2006.10.08
ListBox





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский