Форум: "Основная";
Текущий архив: 2002.10.31;
Скачать: [xml.tar.bz2];
Внизкое-что про TThread Найти похожие ветки
← →
pirat (2002-10-21 18:07) [0]Вот что я не понял из хелпа:
А нужно ли делать Thread.Terminate перед Thread.Free.
А нужно(можно) ли делать CloseHandle ?
А вот, допустим у меня в треде процедура Execute завершиласть. Можно ли тред еще раз запустить (или нужно его Free а потом Create )? Пробую еще раз сделать Execute, но это подвешивает отсновной поток.
← →
Александр Спелицин (2002-10-21 19:00) [1]Используйте CreateThread (WinApi) вместо TThread.
TThread в VCL реализован весьма коряво. На мой взгляд с потоками лучше работать на чистом WinAPI. Либо писать СВОЙ класс-оболочку.
← →
pirat (2002-10-21 19:08) [2]А как же синхронизация???
А я в начале так и делал, только у меня переодически возникали конфликты при доступе к Canvas. Мой поток рисовал там ИшеИдеб а основной поток пытался в это же время делать Paint.
По поводу первого вопроса: проверял в дебаггере, Thread.Free не оказывает НИКАКОГО воздействия на объект Thread, хотя процедура уже завершилась. :(
Почему так?
← →
VaS (2002-10-21 19:20) [3]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;
← →
TTCustomDelphiMaster (2002-10-21 19:54) [4]F1 - TThread.FreeOnTerminate
← →
pirat (2002-10-21 22:38) [5]Спасибо, попробую. А то в моем варианте процесс все время вызывал исключение (оно и понятно) и уходил из под отладчика (а вот это я не понял до сих пор).
← →
nikolab6 (2002-10-22 00:36) [6]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;
← →
VaS (2002-10-22 09:01) [7]Нет, не self. Это - переменная, которая пренадлежит классу-владельцу нити (или глобальная переменная). Для чего ее обнулять? Чтобы при повторном создании нитки определить, успела ли она завершиться после последнего Terminate. Это нужно для исключения одновременного существования более одной такой нитки.
← →
Nomad.kz (2002-10-22 10:27) [8]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 вполне хватает на обычные извраты.
← →
SottNick (2002-10-22 11:16) [9]убить поток
if ReadThread<>nil
then
begin
ReadThread.Suspend;
ReadThread.Free;
ReadThread:=nil;
end;
а в ReadThread.Execute;
я обычно делаю бесконечный цикл
а поток управляется путём
SetEvent(eventAvailableStart);
WaitForSingleObject(eventThreadMeasure, INFINITE);
← →
Smithson (2002-10-22 11:29) [10]Только поток, убитый таким образом, об этом не узнает и не завершит свою работу корректно (например, не запишет результаты работы в файл), поскольку Suspend запретит его выполнение, а Free исполняется основным потоком. Если только перекрывать Destroy потока.
← →
SottNick (2002-10-22 11:36) [11]Я понимаю, что не завершит свою работу корректно.
Пусть, если он корректно завершился или харакири сделает или флажок выставит или сообщение вышлет.
← →
SottNick (2002-10-22 11:58) [12]упс!
однако память не освобождается
люди!
как правильно убить поток из основного приложения, даже если тот не хочет?
if ReadThread<>nil
then
begin
ReadThread.Suspend;
ReadThread.Destroy;
ReadThread:=nil;
end;
вроде не помогает
← →
pirat (2002-10-22 12:15) [13]Ну и вопросы :))
А вот на winapi было бы проще TerminateThread и все дела
← →
Nomad.kz (2002-10-22 13:03) [14]да все просто:
если <поток>.FreeOnTerminate = true, то <поток>.Terminate убивает его, никаких дестроев не надо (естественно, если в <поток>.Execute все время проверяется <поток>.Terminated).
← →
Smithson (2002-10-22 13:05) [15]> 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;
← →
SottNick (2002-10-22 13:54) [16]В том то и проблема
поток остановлен насильно,
поэтому сам он себя никак не убъет
приходится
Th.FreeOnTerminate := True;
Th.Terminate;
или
Th.Free;
и всё равно
Утечки памяти составляют по 8 килограмм за раз
не так уж и мало.
← →
Smithson (2002-10-22 14:04) [17]А поток внутри себя (в execute) память распределяет? Создает объекты, строки? И после Terminate их освобождает?
← →
Alex_Sudakov (2002-10-22 14:25) [18]Вообще лучше отслеживать завершение потока через Mutex"ы (CreateMutex). Они собственно, для этого и предназначены...:)
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2002.10.31;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.008 c