![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как правильно удалить поток в различных ситуациях
Kolan © (2006-05-30 19:04:00)Здравствуйте,
Меня мучает вопрос как коректно удалить поток. Под словом удалить подразумеваю вызвать деструктор.
Кое кокие знания у меня есть, но что я делаю не так понять не могу.
1. Вопрос номер один:
Каким образом удаляют поток?
- Мой ответ: Нужно вызвать методTerminate. И незабыть выставитьFreeOnTeminateвTrue
Так?
- Я знаю, чтоTerminateпросто устанавливаетTerminatedв True, поэтому его нужно самому проверять.
Если 1 верно(если нет, то где я не прав), то вопрос номер 2:
Как быть в следующих случаях:
а).FreeOnTerminateзаписано внутриExecute. Поток зоздался спящим, так и небыл "разбужен", и его надо удалить. Те доFreeOnTerminateдело даже не дошло...
б). Поток чего-то ждет. Например ф-циейWaitForSingleObject. И его надо удалить.
в). В потоке используется экземпляр ранее написанного класса. И в этом классе совершаются долгие вычисления. Сатарый класс трогать на хочется. Тогда как быть и как проверятьTerminated.
Во всех этих случиях у меня не вызывается деструктор потока...
Kolan (2006-06-01 13:14:00) [41]Вот реальная история:
Поток заснул:
if ReadIndex >= WriteIndex then
begin
Suspend;
end
Теперь закрываю приложение:
FPackageExtractor.Terminate;
FPackageExtractor.Resume;
По идее должен попрасть в начало Execute:
while not Terminated do (*)
begin
Ставлб BreakPoint перед закрытием приложения наwhile not Terminated do.
До точки остонова дело не доходит. Все закрывается Деструктор. Естественно не вызвался.
Что я сделел не так?
Пусик (2006-05-31 21:45:00) [42]
> Или вы имеете вв виду объект ядра? Просто CLoseHandle?
Я имел ввиду, что надо разрушить объект, дескриптор которого используется в функции ожидания. Ожидание немедленно будет прервано и поток продолжит работу. Дальше уже можно корректно завершать.
> А что разве в этом случае будет вызван деструктор?
Просто после TertminateThread вызови метод Free и все.
В 16 посте лишнее - FreeOnTerminate := True;
Kolan (2006-05-31 21:38:00) [43]
> Разрушить ожидаемый объект
Я жду событие... Или вы имеете вв виду объект ядра? ПростоCLoseHandle?
> TerminateThread
Как бы жестко убивать не хочется... А что разве в этом случае будет вызван деструктор?
Пусик (2006-05-31 21:33:00) [44]
> 2. TerminateThread, затем Resume
+ FreeOnTerminate := True;
Пусик (2006-05-31 21:33:00) [45]
> б. Поток ждет когда в Com порт придет информация.
Два варианта:
1. Разрушить ожидаемый объект(который указан в WaitForSingleObjec). Дальше по накатанной колее.
2. TerminateThread, затем Resume
Kolan (2006-05-31 21:27:00) [46]Все случаи(а, б, в) реальные.
а. Тут пример не нужен.
б. Поток ждет когда в Com порт придет информация.
в. Любой пример в стаом объекте сидит долгий цикл. Рещил завернуть в поток...
Пусик (2006-05-31 21:26:00) [47]
> tesseract © (31.05.06 21:25) [11]
>
> перекрываем free ?????
А что так волнуешься? Что в этом особенного?
Пусик (2006-05-31 21:25:00) [48]
> API © (31.05.06 00:33) [8]
И в то же время есть еще олдин вариант - менее пугающий для новичков:
procedure TMyThread.Release;
begin
Terminate;
FreeOnTerminate := True;
Resume;
end;
tesseract (2006-05-31 21:25:00) [49]перекрываем free ?????
Бакнелл рвёт оставшиеся волосы.......
Пусик (2006-05-31 21:22:00) [50]
> atruhin © (31.05.06 05:50) [9]
>
>
> > [6] Пусик © (31.05.06 00:00)
>
> Девушка ну не баламутьте людей. Им же жить еще.
Предлагаю тебе не болтать ерундой, если нет знаний по теме топика.
> API © (31.05.06 00:33) [8]
> Как мило... :)
Спасибо, я тоже так думаю-)
atruhin (2006-05-31 05:50:00) [51]
> [6] Пусик © (31.05.06 00:00)
Девушка ну не баламутьте людей. Им же жить еще.
> Kolan © (30.05.06 19:04)
Опиши конкретную проблемму если есть. Тогда подскажут. На 5 теоретических вопросов (описанных в любой книге по программированию в windows) вряд ли кто ответит. Описание работы с потоками у Рихтера занимает не менее 100 страниц, ты хочеш чтобы тебе их сюда перепечатали?
> Самому интересно - будет ли Рихтер против следующего кода
> while not Terminated do begin
> if WaitForSingleObject (h, 20000) <> WAIT_FAILED then begin
Не переживай. Увидит повешается! :). В твоем случае при нажатии на кнопку завершения программы придеться ждать 20 сек для выхода из WaitForSingleObject. Думаю более корректный вариант, для выхода из множества потоков, создать Event для выхода и ожидать его WaitForMultipleObjects
API (2006-05-31 00:33:00) [52]4. Перекрой процедуру Free:
procedure TMyThread.Free(Sender: TObject);
begin
FreeOnTerminate := True;
Terminate;
Resume;
inherited;
end;
Как мило... :)
Пусик (2006-05-31 00:03:00) [53]+ жестокое уничтожение потока:
TerminateThread(MyThread.Handle,0);
MyThread.Free;
Пусик (2006-05-31 00:00:00) [54]
> а). FreeOnTerminate записано внутри Execute.
Вариантов масса.
1. Устанавливай FreeOnTerminate в конструкторе.
2. Последовательность действий:
- Terminate
- Resume
3. Не устанавливай FreeOnTerminate в True, а всегда используй:
- Treminate
- Resume
- WaitFor
- Free
4. Перекрой процедуру Free:
procedure TMyThread.Free(Sender: TObject);
begin
FreeOnTerminate := True;
Terminate;
Resume;
inherited;
end;
Kolan (2006-05-30 19:15:00) [55]Все удаление делаю в
Destoy, как всегда вообщем.
TUser (2006-05-30 19:11:00) [56]
>
> Убиваю обычно при закрытии приложения. И MemProof сообщает
> о не уничтоженных объектах(поля потока) итд...
OnTerminate? Хотя при закрытии приложения это не важно.
TUser (2006-05-30 19:10:00) [57]Самому интересно - будет ли Рихтер против следующего кода
while not Terminated do begin
if WaitForSingleObject (h, 20000) <> WAIT_FAILED then begin
do something
break;
end;
end;
Вроде бы спим и ждем, но все время просыпаемся. Т.е. получается некоторый аналог sleep (20000), хотя и с использованием виндусовской синхронизации.
Kolan (2006-05-30 19:09:00) [58]
> TUser © (30.05.06 19:07) [1]
Убиваю обычно при закрытии приложения. И MemProof сообщает о не уничтоженных объектах(поля потока) итд...
TUser (2006-05-30 19:07:00) [59]Всегда можно вызвать TerminateThread с соотвествующим хендлом. Но грамотнее наверное будет продумать приложение так, чтобы поток корретко убивался, если его переодически приходится убивать.