Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.05.16;
Скачать: [xml.tar.bz2];

Вниз

Как ПРАВИЛЬНО останавливать Treadы в Delphi?   Найти похожие ветки 

 
Leonardo_de_caprio   (2004-04-26 21:35) [0]

Я делаю так:
из формы проекта пишу


 If not myThread.Suspended then
   myThread.Suspend;
 myThread.Terminate;
 myThread.Free;
 myThread:=nil;


но если поток сильно нагружен( идет работа - цикл), то он разваливается в итоге. Как надо?


 
TUser ©   (2004-04-26 21:50) [1]

Надо показать код Экзекьюта. Телепатически сообрахаю, что скорее всего не проверяется Terminated. В VCL написано

procedure TThread.Terminate;
begin
 FTerminated := True;
end;

Соотвественно в потоке (в Execute) надо писать
while not Termanated do begin
  ...
  end;


 
тихий вовочка ©   (2004-04-26 21:55) [2]

В самом потоке делать

repeat

if Terminated then
 break;

until false;

А в главной проге так как ты и делал.


 
Leonardo_de_caprio   (2004-04-26 22:10) [3]

Вот мой Execute


procedure TmyThread.Execute;
begin
While not Terminated do
 DoWork;
end;


а то что выше я написал, я по нажатию на батон выполняю


 
Piter ©   (2004-04-26 22:24) [4]

тихий вовочка (26.04.04 21:55) [2]
А в главной проге так как ты и делал


неправильный ответ. Не так надо, нефиг у потоков вообще Free вызывать... вдруг он еще на завершился?

Надо в Execute выставить FreeOnTerminate:=true
Тогда объект класса TThread сам уничтожется после завершения потока.

А если надо быть уверенным, что поток завершился, то WaitForSingleObject с нужным временем ожидания...


 
Piter ©   (2004-04-26 22:25) [5]

Leonardo_de_caprio   (26.04.04 22:10) [3]
While not Terminated do


у тебя что, поток работает пока его не остановят... бесконечные вычисления?

P.S. А про поткои ты не у Архангельского читал?


 
Leonardo_de_caprio   (2004-04-26 22:37) [6]

>Piter
Да пока его не остановят, по нажатию на батон

Ща попробую FreeOnTerminate:=true


 
Leonardo_de_caprio   (2004-04-26 22:43) [7]

>Тогда объект класса TThread сам уничтожется после завершения потока

хм, я то поток сам уничтожать хочу. Я заменил terminate на
FreeOnTerminate. Вроде пока работает


 
Leonardo_de_caprio   (2004-04-26 22:57) [8]

Мужики Help! Я сейчас глянул в Task Managere в Threads потоки при myPotok.terminate или myPotok.FreeOnTerminate:=true не уменьшаются! Че за ерунда?


 
Cobalt ©   (2004-04-26 23:03) [9]

А в DoWork у тебя никакого цикла, или ожидания нет?


 
Leonardo_de_caprio   (2004-04-26 23:06) [10]

есть цикл, но он имеет окончание


 
Leonardo_de_caprio   (2004-04-26 23:42) [11]

Вот ОНО!


procedure TForm1.Button1Click(Sender: TObject);
begin
If Assigned(myPotok) then
 myPotok.Free;
myPotok:=TmyThread.Create(true);
myPotok.Resume;
end;


и триды дохнут! Дело утопающего в умной книге.


 
Piter ©   (2004-04-26 23:56) [12]

Leonardo_de_caprio   (26.04.04 22:43) [7]
хм, я то поток сам уничтожать хочу


я те говорю, что объект TThread завершится после завершения потока, ибо нафига он вообще нужен без потока то?

TThread только оболочка для использования объекта ядра поток в windows


 
Игорь Шевченко ©   (2004-04-27 00:02) [13]

TThread.WaitFor


 
Leonardo_de_caprio   (2004-04-27 00:07) [14]

>Piter
Что в твоем понимании объекта TTread?
Какой метод ты вызываешь чтобы принудительно завершить поток?

Тупой я, код приведи старт/стоп потока. Выше написанные 4 строки пашут и мне до лампочки как ведет себя объект после terminate
Если как ты говоришь он уничтожен, так почему Free в этом случае не дает exception? Правильно ты же сам сказал что это оболочка :)
которую надо фрикать


 
Mim1 ©   (2004-04-27 05:15) [15]

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

type
 myth = calss(tthread)
   ...
   cname :string;
 end;
 tform1 = class(tform)
   ...
   procedure Button1Click(sender:tobject);
   ...
   th: myth;
 end;

procedure myth.setc;
begin
 form1.th := nil;
end;

procedure myth.execute;
begin
 while not treminated do
   begin
//      здесь делаем необходимую работу
   end;
 sincronize(setc);
end;

procedure Tform1.Button1Click(sender:tobject);
begin
 if th = nil then
   begin
     th := myth.create(true);
     th.freeonterminate := true;
     th.resume;
   end
 else
   th.terminated := true;      
end;


 
Evgeny V ©   (2004-04-27 07:32) [16]


> If not myThread.Suspended then
>    myThread.Suspend;

>  myThread.Terminate;
>  myThread.Free;
>  myThread:=nil;

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


 
Тимохов ©   (2004-04-27 11:07) [17]

Надо так

myThread.Terminate;
myThread.WaitFor;
myThread.Free;
myThread:=nil;


либо так

myThread.Terminate;
при условии, что у потока стоит FreeOnTerminate := True;


 
panov ©   (2004-04-27 11:14) [18]

Приведи код класса потока, иначе пустой разговор.


 
panov ©   (2004-04-27 11:32) [19]

Несколько замечаний:

1. Если от потока необходимо получать код возврата, то необходимо флаг FreeOnTerminate := False;

В этом случае схема такая:

 в конструкторе:

 begin
   inherited CReate(True);
   FreeOnTermintate := False;
// инициализация переменных
   Resume;  
 end;

 в методе Execute:
 while not Terminated do

   ...  
   if Terminated then Break;
   ...  
 end;
 ReturnValue := 0; //Код возврата

 в вызывающей программе:
 MyThread := TMyThread.Create(...);
 Ret := MyThread.WaitFor;
 MyThread.Free;

 Либо если поток терминируется вручную:
 MyThread := TMyThread.Create(...);
 MyThread.Terminate;
 Ret := MyThread.WaitFor;
 MyThread.Free;

2. Инициализацию переменных нужно делать до старта процедуры потока, либо в методе Execute(что, в случае передачи параметров потоку, в методе Execute сделать невозможно).
Процедура потока стартует немедленно после вызова inherited, поэтому поток нужно создавать в спящем состоянии.

Схема такая:
 constructor TMyThread.Create(...);
 inherited Create(True);
 //инициализация переменных
 Resume;

3. В случае FreeOnTerminate := True нет необходимости вызывать метод Free для потока после его завершения.
 В этом случае код возврата получить не удастся.



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2004.05.16;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.038 c
14-1082786883
uny
2004-04-24 10:08
2004.05.16
Про другую сторону - линуксы всякие


3-1082109937
ksa3003
2004-04-16 14:05
2004.05.16
Выборка пустых значений


1-1083336754
siriusP
2004-04-30 18:52
2004.05.16
Hint для ComboBox ???


14-1083060913
syte_ser78
2004-04-27 14:15
2004.05.16
ping


1-1083291386
CyBeR
2004-04-30 06:16
2004.05.16
Переход другую форму с помощью закладок





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