Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
4-101597
Igor_thief
2002-09-14 12:17
2002.10.31
Hook


4-101598
dimon79
2002-09-18 12:50
2002.10.31
GetTickCount


6-101402
XPatriot
2002-08-24 17:06
2002.10.31
SMTP-сервер.


14-101486
VictorT
2002-10-11 17:41
2002.10.31
Как из аськи перенести контакт-лист и историю на другую машину?


3-101137
Ditrix
2002-10-09 11:52
2002.10.31
запрос с группировкой по 1 символу





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