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

Вниз

Запустить 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.57 MB
Время: 0.008 c
2-1235320820
KillaTank
2009-02-22 19:40
2009.04.12
Модальное окно в ДБ


2-1234471401
KillaTank
2009-02-12 23:43
2009.04.12
Создание DBF файла во время работы приложения


2-1235121964
321
2009-02-20 12:26
2009.04.12
быстро пробежать по записям


2-1235503620
dmitry_12_08_73
2009-02-24 22:27
2009.04.12
Проверка на открытое окно в приложении


15-1234245698
zdm
2009-02-10 09:01
2009.04.12
перекодировка DOS Delphi 2009





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