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

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

кое-что про TThread [D5, Win95/98]


pirat ©   (2002-10-21 18:07:00) 

Вот что я не понял из хелпа:
А нужно ли делать Thread.Terminate перед Thread.Free.
А нужно(можно) ли делать CloseHandle ?
А вот, допустим у меня в треде процедура Execute завершиласть. Можно ли тред еще раз запустить (или нужно его Free а потом Create )? Пробую еще раз сделать Execute, но это подвешивает отсновной поток.


Alex_Sudakov   (2002-10-22 14:25:00) [1]

Вообще лучше отслеживать завершение потока через Mutex"ы (CreateMutex). Они собственно, для этого и предназначены...:)


Smithson   (2002-10-22 14:04:00) [2]

А поток внутри себя (в execute) память распределяет? Создает объекты, строки? И после Terminate их освобождает?


SottNick   (2002-10-22 13:54:00) [3]

В том то и проблема
поток остановлен насильно,
поэтому сам он себя никак не убъет

приходится

Th.FreeOnTerminate := True;
Th.Terminate;

или

Th.Free;


и всё равно
Утечки памяти составляют по 8 килограмм за раз
не так уж и мало.


Smithson   (2002-10-22 13:05:00) [4]

> pirat © (22.10.02 12:15)

TerminateThread(ReadThread.Handle, 0) убьет поток наверняка, даже если он "висит" (остановлен ОС по своим соображениям, например из-за ошибки), но при этом сбежит немного памяти.

В принципе, ReadThread.Free из другого потока должно корректно закрыть лавочку и освободить всю память.
Я делаю примерно так:

Th: Thread;
...
// Надо остановить работу потока
Th.FreeOnTerminate := True;
Th.Terminate; // Дать команду
sleep(100); // пусть попробует сам кончится
try
TerminateThread(Th.Handle); // Убьем насильно
except
// Ошибка возникнет, если поток уже умер. Проигнорируем ее.
end;


Nomad.kz   (2002-10-22 13:03:00) [5]

да все просто:
если <поток>.FreeOnTerminate = true, то <поток>.Terminate убивает его, никаких дестроев не надо (естественно, если в <поток>.Execute все время проверяется <поток>.Terminated).


pirat   (2002-10-22 12:15:00) [6]

Ну и вопросы :))
А вот на winapi было бы проще TerminateThread и все дела


SottNick   (2002-10-22 11:58:00) [7]

упс!
однако память не освобождается
люди!
как правильно убить поток из основного приложения, даже если тот не хочет?


if ReadThread<>nil
then
begin
ReadThread.Suspend;
ReadThread.Destroy;
ReadThread:=nil;
end;

вроде не помогает


SottNick   (2002-10-22 11:36:00) [8]

Я понимаю, что не завершит свою работу корректно.
Пусть, если он корректно завершился или харакири сделает или флажок выставит или сообщение вышлет.


Smithson   (2002-10-22 11:29:00) [9]

Только поток, убитый таким образом, об этом не узнает и не завершит свою работу корректно (например, не запишет результаты работы в файл), поскольку Suspend запретит его выполнение, а Free исполняется основным потоком. Если только перекрывать Destroy потока.


SottNick   (2002-10-22 11:16:00) [10]

убить поток

if ReadThread<>nil
then
begin
ReadThread.Suspend;
ReadThread.Free;
ReadThread:=nil;
end;

а в ReadThread.Execute;
я обычно делаю бесконечный цикл
а поток управляется путём

SetEvent(eventAvailableStart);
WaitForSingleObject(eventThreadMeasure, INFINITE);


Nomad.kz   (2002-10-22 10:27:00) [11]

2VaS © (21.10.02 19:20)
Еще лучше завести флажок и пасти его, а не Terminate, и делать:

procedure TTr.Execute;
begin
while NeedThread do
begin
//усиленно работаем :)
end;
Terminate;
end;

чем это лучше? Terminated для того и предназначен, чтобы за этим смотреть ... объяснитесь, пожалуйста!

2Александр Спелицин © (21.10.02 19:00)
В дельфях потоки реализованы не коряво, а для определенного круга задач, т.е. класса TThread вполне хватает на обычные извраты.


VaS   (2002-10-22 09:01:00) [12]

Нет, не self. Это - переменная, которая пренадлежит классу-владельцу нити (или глобальная переменная). Для чего ее обнулять? Чтобы при повторном создании нитки определить, успела ли она завершиться после последнего Terminate. Это нужно для исключения одновременного существования более одной такой нитки.


nikolab6   (2002-10-22 00:36:00) [13]

S interesom chital. Menia toje interesuiut TTread. V kode destructora VaS© ne ponial liniu Tr:=nil? - eto ne Self?

>> destructor TTr.Destroy;
>> begin
>> //однуляем указатель на себя
>> Tr:=nil;
>> inherited;
>> end;


pirat   (2002-10-21 22:38:00) [14]

Спасибо, попробую. А то в моем варианте процесс все время вызывал исключение (оно и понятно) и уходил из под отладчика (а вот это я не понял до сих пор).


TTCustomDelphiMaster   (2002-10-21 19:54:00) [15]

F1 - TThread.FreeOnTerminate


VaS   (2002-10-21 19:20:00) [16]

TTr = class(TThread)
protected
procedure Execute; override;
public
constructor Create;
destructor Destroy; override;
end;

procedure TTr.Execute;
begin
while not Terminated do
begin
//усиленно работаем :)
end;
end;

constructor TTr.Create;
begin
inherited Create(true);
FreeOnTerminate:=true;
Resume;
end;

destructor TTr.Destroy;
begin
//однуляем указатель на себя
Tr:=nil;
inherited;
end;

//создаем нитку
var
Tr: TTr;
...
Tr:=TTr.Create;
...
//убиваем нитку
Tr.Terminate;
//и идем дальше, а нитка унитожится, когда выйдет тз цикла
Еще лучше завести флажок и пасти его, а не Terminate, и делать:

procedure TTr.Execute;
begin
while NeedThread do
begin
//усиленно работаем :)
end;
Terminate;
end;



pirat   (2002-10-21 19:08:00) [17]

А как же синхронизация???
А я в начале так и делал, только у меня переодически возникали конфликты при доступе к Canvas. Мой поток рисовал там ИшеИдеб а основной поток пытался в это же время делать Paint.

По поводу первого вопроса: проверял в дебаггере, Thread.Free не оказывает НИКАКОГО воздействия на объект Thread, хотя процедура уже завершилась. :(
Почему так?


Александр Спелицин   (2002-10-21 19:00:00) [18]

Используйте CreateThread (WinApi) вместо TThread.
TThread в VCL реализован весьма коряво. На мой взгляд с потоками лучше работать на чистом WinAPI. Либо писать СВОЙ класс-оболочку.


Наверх

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