Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как правильно удалить поток в различных ситуациях


Страницы:   1 2 3

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 с соотвествующим хендлом. Но грамотнее наверное будет продумать приложение так, чтобы поток корретко убивался, если его переодически приходится убивать.


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо