Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.04.12;
Скачать: CL | DM;

Вниз

Запустить TThread повторно?   Найти похожие ветки 

 
Cobalt ©   (2009-02-21 15:14) [0]

Есть у меня один поток, который обходит каталоги, считает контрольные суммы файлов.
Но каждый раз после окончания работы приходится пересоздавать объект :-(

Вопрос такой: можно ли после окончания исполнения потока повторно использовать объект TThread ?

Например, запустив его метод Create - будет ли создан новый объект TThread, который повиснет в памяти, или он только отработает свой код, заново запустив WinAPI-ый поток исполняться?


 
Eraser ©   (2009-02-21 15:19) [1]

> Вопрос такой: можно ли после окончания исполнения потока
> повторно использовать объект TThread ?

можно, и не только после окончания.


 
Cobalt ©   (2009-02-21 15:23) [2]

Хотелось бы видеть нечто вроде
FireThread
проверяя завершение потока по Terminated
не удаляя существующего объекта.


 
Eraser ©   (2009-02-21 15:50) [3]

> [2] Cobalt ©   (21.02.09 15:23)

для этого можно использовать TThread или любой другой класс, вызывая его метод Execute из другого потока, созданного к примеру через BeginThread или тот же TThread.


 
Тын-Дын ©   (2009-02-21 16:56) [4]


> для этого можно использовать TThread или любой другой класс,
>  вызывая его метод Execute из другого потока, созданного
> к примеру через BeginThread или тот же TThread.


Что сказать-то вообще хотел?


> Cobalt ©   (21.02.09 15:14) 



> Вопрос такой: можно ли после окончания исполнения потока
> повторно использовать объект TThread ?


Посмотри простой пример:

type

 TThrProc=procedure;

 TThrTest=class(TThread)
 private
   FThrProc: TThrproc;
   FEvent: THandle;
   FExecEvent: THandle;
 protected
   procedure Execute; override;
 public
   constructor Create;
   destructor Destroy; override;

   function Exec(Proc: TThrProc): Boolean;
   procedure EndThread;
 end;

var
 Thr: TThrTest;

implementation

procedure ProcThr1;
begin
 MessageBox(0,"qqq","qqq",MB_OK);
end;

procedure ProcThr2;
begin
 Sleep(1000);
 MessageBox(0,"sss","sss",MB_OK);
end;

{ TThrTest }

constructor TThrTest.Create;
begin
 inherited Create(True);
 FEvent := CreateEvent(nil,False,False,"");
 FExecEvent := CreateEvent(nil,False,False,"");
 FreeOnTerminate := True;
 Resume;
 WaitForSingleObject(FExecEvent, INFINITE);
 SetEvent(FExecEvent);
end;

destructor TThrTest.Destroy;
begin
 CloseHandle(FEvent);
 CloseHandle(FExecEvent);
 inherited;
end;

procedure TThrTest.Execute;
begin
 SetEvent(FExecEvent);
 while not Terminated do
 begin
   if Terminated then Exit;
   try
     if Assigned(FThrProc) then FThrProc;
     FThrProc := nil;
   except
     //
   end;
   SignalObjectAndWait(FExecEvent,FEvent,INFINITE,False);    
 end;
end;

function TThrTest.Exec(Proc: TThrProc): Boolean;
begin
 Result := False;
 if WaitForSingleObject(FExecEvent,0)=WAIT_OBJECT_0 then
 begin
   Result := True;
   FThrProc := Proc;
   SetEvent(FEvent);
 end;

end;

procedure TThrTest.EndThread;
begin
 Terminate;
 SetEvent(FEvent);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 if not Assigned(Thr) then Thr := TThrTest.Create;
 if not Thr.Exec(@ProcThr1) then ShowMessage("Busy");
 Sleep(2000);
 if not Thr.Exec(@ProcThr2) then ShowMessage("Busy");

end;


 
DVM ©   (2009-02-21 17:28) [5]


> Есть у меня один поток, который обходит каталоги, считает
> контрольные суммы файлов.
> Но каждый раз после окончания работы приходится пересоздавать
> объект :-(
>

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


 
Cobalt ©   (2009-02-21 18:18) [6]

> DVM ©   (21.02.09 17:28) [5]
Так еще ж нужно знать, что он обошел всё, и всё подсчитал.
И чтобы для этого не добавлять кучу дополнительных полей...


 
Медвежонок Пятачок ©   (2009-02-21 18:42) [7]

в конце execute postmessage наружу и по приемеу resume ему снаружи

либо тупо цикл в сам execute

детские какие-то вопросы.

"повторно использовать"

ломает create что ли вызвать еще раз?


 
Тын-Дын ©   (2009-02-21 20:54) [8]


> детские какие-то вопросы.


Вряд ли ты пытался на них для себя кодом ответить.


 
Медвежонок Пятачок ©   (2009-02-21 21:05) [9]

в чем-то ты прав. я не пытался ответить на них (вопросы) потому что таких вопросов у меня не возникало никогда


 
Медвежонок Пятачок ©   (2009-02-21 21:10) [10]

Посмотри простой пример:

type

TThrProc=procedure; .....


этот пример лучше никому не показывать, а самому втихаря переться от своей крутости.
За какой надобностью здесь потребовалось использовать евенты?


 
Riply ©   (2009-02-21 21:22) [11]

> [0] Cobalt ©   (21.02.09 15:14)
> Вопрос такой: можно ли после окончания исполнения потока повторно использовать объект TThread ?

Например, не выходить из него, а ожидать события или сообщения.

> [7] Медвежонок Пятачок ©   (21.02.09 18:42)
> ломает create что ли вызвать еще раз?

Если бы ты знал, как "ломает", ибо это довольно "тяжелая" для системы операция (создание нити).


 
Медвежонок Пятачок ©   (2009-02-21 21:24) [12]

а евент это конечно очень дешевый для процесса объект


 
Riply ©   (2009-02-21 21:51) [13]

> [12] Медвежонок Пятачок ©   (21.02.09 21:24)
> а евент это конечно очень дешевый для процесса объект

Честно говоря - не знаю степень его (Eventa) "тяжести" :)
Но с нитями неоднократно ставила различные опыты.
Например, были очень старые исходники Rouse`а - перебор открытых файлов.
Там он на каждый запрос создавал нить ( сканирование занимало ~ 30-40 сек )
Я попробовала не уничтожать нить (если нет необходимости, а повторно использовать).
Сканирование стало занимать доли секунды. Разница на порядки :)
Числа по памяти - могу ошибаться (давно это было), но то что разница измерялась порядками - "эт точто" :)
Да ты и сам можешь проверить, написав простой пример:
(пересоздание нити на каждый запрос и обращение к уже существующей ).
Результат тебя впечатлит :)


 
Медвежонок Пятачок ©   (2009-02-21 21:54) [14]

сомневаюсь что меня это впечатлит.
я в основном занимаюсь проектированием систем 24х7.
пришел клиент - создается нить.
новая.
и никто еще пока не жаловался, что медленно обслуживается именно из за того, что нити пересоздаются.


 
Riply ©   (2009-02-21 22:03) [15]

> [14] Медвежонок Пятачок ©   (21.02.09 21:54)

Очень сильно зависит от интенсивности создания.
Предполагаю, что при "наплыве" клиентов - это может стать заметным.
P.S.
Ну и не зря же ThreadPool придумали :)


 
Медвежонок Пятачок ©   (2009-02-21 22:06) [16]

да. сред пул это как раз то что требуется кобальту.
или мы сейчас  решаем что требуется мне?


 
Riply ©   (2009-02-21 22:09) [17]

>  [16] Медвежонок Пятачок ©   (21.02.09 22:06)

Ты чего это такой агрессивный ? :)
Мы просто мирно обсуждали "тяжесть" создания нити,
а отнюдь не качество твоего кода :)


 
Медвежонок Пятачок ©   (2009-02-21 22:12) [18]

да я вообще пушистый.


 
Riply ©   (2009-02-21 22:15) [19]

> [18] Медвежонок Пятачок ©   (21.02.09 22:12)
> да я вообще пушистый.

Если еще и белый, то тогда ладно :)


 
Тын-Дын ©   (2009-02-21 22:53) [20]


> Медвежонок Пятачок ©   (21.02.09 21:10) [10]
>За какой надобностью здесь потребовалось
> использовать евенты?


Тебе интересно, или тебе подумать лень?

Конечно же, проще переться от собственной крутости, бросаясть фразами навроде [7].

Подумаешь - ответишь для себя.
Думать не хочешь - твоё дело.


 
Тын-Дын ©   (2009-02-21 22:54) [21]


> Медвежонок Пятачок ©   (21.02.09 21:05) [9]
> в чем-то ты прав. я не пытался ответить на них (вопросы)
> потому что таких вопросов у меня не возникало никогда


Ну не пытался, тогда стоит ли начинать пытаться? Тем более без практической и теоретической подготовки?


 
Cobalt ©   (2009-02-22 00:16) [22]

Мой вопрос был большей частью по эстетической линии:
Нет у потока свойства, которое бы показывало, работает он или нет (даже если Suspended)

Суть вопроса:
Есть несколько задач по обходу каталогов.
Сначала я сделал их в основном потоке, выводя в мемо результат обхода (с ProcessMessages для отображения пользователю).
Но при этом нажать на кнопку "Остановить процесс" затруднительно.
Вынес работу в отдельный поток, чтобы кнопки были доступны пользователю.

При этом надо обновлять состояние прочих кнопок в соответствии с состоянием работы.
Проще всего - по свойству потока - работает он или уже/еще нет.
К примеру, в Action.OnExecute дернул FThread.Start, а на Action.OnUpdate
actStop.Enabled:=FThread.Running;

а вместо этого приходится делать дополнительные свойства, вручную взводить в Thread.Execute и сбрасывать после:

actStop.Enabled:=(FThread<>nil)and(FThread.InProgress);


 
Медвежонок Пятачок ©   (2009-02-22 00:30) [23]

Тем более без практической и теоретической подготовки?

ты у меня экзамены что ли принимал?


 
Медвежонок Пятачок ©   (2009-02-22 00:33) [24]

Нет у потока свойства, которое бы показывало, работает он или нет (даже если Suspended)

и в чем проблема?
создать свойство с полем и менять его в execute?
не проблема.
только зачем?
для того что бы запустив поток тупо крутить цикл и проверять не приняло ли свойство нужное значнение?
дурь это.


 
Тын-Дын ©   (2009-02-22 00:33) [25]


> Нет у потока свойства, которое бы показывало, работает он
> или нет (даже если Suspended)


А что в твоём понимании "работает"?

Поток может находиться только в двух состояниях - спит и не спит.

Поточная функция может ожидать неких событий. В этом случае поток работает или нет?


 
Тын-Дын ©   (2009-02-22 00:35) [26]


> Медвежонок Пятачок ©   (22.02.09 00:30) [23]
> Тем более без практической и теоретической подготовки?ты
> у меня экзамены что ли принимал?


По твоему высказыванию видно -

> За какой надобностью здесь потребовалось использовать евенты?


Особенно вот это показывает полное непонимание предметной области-


> этот пример лучше никому не показывать, а самому втихаря
> переться от своей крутости.


 
Тын-Дын ©   (2009-02-22 00:36) [27]


> Медвежонок Пятачок ©


Если интересно понять, почему именно так, а не по другому - задай конкретные вопросы - по каждой строке кода отвечу.


 
Медвежонок Пятачок ©   (2009-02-22 00:36) [28]

евенты здесь нафик не нужны.

они могут понадобиться только от полного непонимания элементарный вещей.


 
Тын-Дын ©   (2009-02-22 00:40) [29]


> они могут понадобиться только от полного непонимания элементарный
> вещей.


Давай конкретнее? Не будем просто так языком чесать?


 
Германн ©   (2009-02-22 00:45) [30]


> Тын-Дын ©   (22.02.09 00:36) [27]


> Медвежонок Пятачок ©   (22.02.09 00:36) [28]

Классный спор!
Один доказывает, что Фома прав, поскольку он не забыл надеть шляпу, а другой доказывает, что Фома не прав, поскольку в отличие от Ерёмы у Фомы ноги кривые. :)
И ни один, ни другой не приводят в доказательство никаких фактов.
Хотя чету тут удивляться? Достаточно взглянуть на ники! :)

P.S. "Про ники" надеюсь без обид?
Попробуйте сами взглянуть на это со стороны.


 
Медвежонок Пятачок ©   (2009-02-22 00:51) [31]

Давай конкретнее? Не будем просто так языком чесать?

Давай.
Уточним, в чем суть спора.
создать один экземпляр нитки и иметь возможность запустить ее много раз повторно без пересоздания, но только тогда, кода она закончила всю прикладную работу с предыдущего вызова?

Верно? Я ничего не упустил?


 
Тын-Дын ©   (2009-02-22 00:57) [32]


> Медвежонок Пятачок ©   (22.02.09 00:51) [31]
> Давай конкретнее? Не будем просто так языком чесать?Давай.
> Уточним, в чем суть спора.создать один экземпляр нитки и
> иметь возможность запустить ее много раз повторно без пересоздания,
>  но только тогда, кода она закончила всю прикладную работу
> с предыдущего вызова?Верно? Я ничего не упустил?


Верно.


 
Медвежонок Пятачок ©   (2009-02-22 01:02) [33]

На.

Вот нитка

constructor TBearPigletThread.CreateIt(AHandle: THandle);
begin
inherited Create(True);
fHandle := AHandle;
FreeOnTerminate := False;
Resume;
end;

procedure TBearPigletThread.Execute;
var i : integer;
begin
for i := 1 to 10 do
 begin
  PostMessage(fHandle,WM_TEST,0,i);
  Sleep(500);
 end;
PostMessage(fHandle,WM_TEST,1,0);
end;

А вот вызывающий модуль

procedure TForm1.OnMsg(var AMsg: TMessage);
begin
case AMsg.WParam of
 0: ListBox1.Items.Add(IntToStr(AMsg.LParam));
 1: Button1.Enabled := True;
end;
end;

var t : TThread = nil;

procedure TForm1.Button1Click(Sender: TObject);
begin
if t = nil then TBearPigletThread.CreateIt(Handle) else t.Resume;
Button1.Enabled := False;
end;


 
Тын-Дын ©   (2009-02-22 01:07) [34]

Хм.
И где здесь повторная используемость?


 
Тын-Дын ©   (2009-02-22 01:08) [35]

Метод Execute заканчивает работу после одного прохода. ПТоток/нить на этому завершает своё существование.


 
Медвежонок Пятачок ©   (2009-02-22 01:09) [36]

Где повторная?
Под баттоном номер один.


 
Медвежонок Пятачок ©   (2009-02-22 01:10) [37]

ПТоток/нить на этому завершает своё существование.

А ты случаем не преподаватель информатики?
Что-то вдруг подумалось.


 
Тын-Дын ©   (2009-02-22 01:14) [38]


> if t = nil then TBearPigletThread.CreateIt(Handle) else
> t.Resume;


Можно пояснить, что здесь происходит?

Переменная t вроде бы не была кроме как nil проинициализирована?


 
Медвежонок Пятачок ©   (2009-02-22 01:19) [39]

какая разница?
зациклить execute и будет тоже самое.
никаких евентов здесь не надо.
переход в начало цикла или брейк - по результату SendMessage


 
Тын-Дын ©   (2009-02-22 01:26) [40]


> какая разница?
>зациклить execute и будет тоже самое.


Что значит - какая разница?
Покажи, как зациклишь.

Этот код в принципе не рабочий.

Ты рабочий код приведи.



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

Текущий архив: 2009.04.12;
Скачать: CL | DM;

Наверх




Память: 0.58 MB
Время: 0.015 c
2-1235547071
cosinus
2009-02-25 10:31
2009.04.12
Манипуляция в чужом приложении.


15-1234632154
Кто б сомневался
2009-02-14 20:22
2009.04.12
Разрешение экрана


1-1207860252
S7r
2008-04-11 00:44
2009.04.12
События OnEnter и OnExit.


15-1234647001
Юрий
2009-02-15 00:30
2009.04.12
С днем рождения ! 15 февраля 2009 воскресенье


15-1234440948
Michael
2009-02-12 15:15
2009.04.12
Алгоритм декодирования JPEG