Форум: "Начинающим";
Текущий архив: 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.OnUpdateactStop.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