Текущий архив: 2007.02.25;
Скачать: CL | DM;
ВнизTThread Найти похожие ветки
← →
RASkov (2007-02-05 03:04) [0]Как правильно стартануть завершившийся но не уничтоженный поток заново?
← →
Новичек © (2007-02-05 04:13) [1]Если экземпляр объекта TThread, то Execute.
← →
MBo © (2007-02-05 05:49) [2]Не надо доводить до завершения.
В Execute должен быть цикл while not Terminated, так вот в его конце сделать suspend, а при надобности resume
← →
iXT © (2007-02-05 09:20) [3]+ FreeOnTerminate:=true
← →
RASkov (2007-02-05 22:35) [4]> [2] MBo © (05.02.07 05:49)
Спасибо. Наверное самое верное решение.
> [3] iXT © (05.02.07 09:20)
Так наоборот же надо - FreeOnTerminate:=False должен быть. Просто не создавать заново поток, а еще раз его стартануть или [2]
← →
MsGuns © (2007-02-05 23:11) [5]ИМХО, крива сама постановка вопроса. Надо не поток стартовать, а необходимую процедуру в потоке, тогда не будет и таких извратов
← →
evvcom © (2007-02-06 09:08) [6]> [4] RASkov (05.02.07 22:35)
> Просто не создавать заново поток, а еще раз его стартануть
> или [2]
Именно [2]! И никаких заново стартануть. А FreeOnTerminate вообще тут не при чем.
← →
RASkov (2007-02-06 11:20) [7]Я полностью согласен с [2], но что, все-таки, имелось ввиду в [5]....?
Если вызвать процедуру потока, то она выполнится в основном потоке, а не в созданном(том в котором она описана).... имхо.
← →
Leonid Troyanovsky © (2007-02-06 11:30) [8]
> RASkov (05.02.07 03:04)
> Как правильно стартануть завершившийся но не уничтоженный
> поток заново?
Формально должно было бы так: Thread.Create(..),
однако, борланды забыли про инициализацию в конструкторе
FTerminated, FFinished и т.д. Ну, или сделать их, хотя бы, protected.
Поэтому, как уже советовали, лучше его не завершать.
Ну, а отдыхать потоку лучше не в suspend, а в WaitFor..Object..
--
Regards, LVT.
← →
Сергей М. © (2007-02-06 11:34) [9]
> что, все-таки, имелось ввиду в [5]....?
procedure TMyThread.Execute;
begin
..
while SomeCondition do begin
...
SomeMethodOfMyThread(SomeParams); // вот что в [5] имелось ввиду
...
end;
..
end;
← →
evvcom © (2007-02-06 11:57) [10]> [8] Leonid Troyanovsky © (06.02.07 11:30)
> борланды забыли про инициализацию в конструкторе
> FTerminated, FFinished и т.д.
А зачем их инициализировать в конструкторе? Любой объект создаваясь инициализирует все свои поля в 0, для буль это и будет False. Все логично.
> Ну, или сделать их, хотя бы, protected.
Зачем? Чтобы дать волю шаловливым ручкам? ИМХО, не стоит.
Доктор сказал в морг, значит в морг, и не фиг заниматься самолечением (c) анекдот :)
← →
Leonid Troyanovsky © (2007-02-06 12:49) [11]
> evvcom © (06.02.07 11:57) [10]
> > борланды забыли про инициализацию в конструкторе
> > FTerminated, FFinished и т.д.
> А зачем их инициализировать в конструкторе? Любой объект
> создаваясь инициализирует все свои поля в 0, для буль это
> и будет False. Все логично.
Всякий конструктор должен уметь работать в двух режимах:
когда объект создается, и когда он иницилизируется (повторно),
или, скажем, вызывается как inherited Create.
Ну, а правильное место для правильной инициализации -
конструктор. По-моему, логично.
> Зачем? Чтобы дать волю шаловливым ручкам? ИМХО, не стоит.
Чтобы можно было выправить чьи-то кривые ручки.
Хм. Особенно умиляет первый вызов inherited Create
(т.е., видимо, чтобы все было как положено).
--
Regards, LVT.
← →
Сергей М. © (2007-02-06 13:57) [12]
> борланды забыли про инициализацию в конструкторе
> FTerminated, FFinished
А какой еще явной инициализации требуют эти поля, если они по умолчанию и так уже равны False, что вполне логично ?
← →
Leonid Troyanovsky © (2007-02-06 14:28) [13]
> Сергей М. © (06.02.07 13:57) [12]
> > борланды забыли про инициализацию в конструкторе
> > FTerminated, FFinished
> А какой еще явной инициализации требуют эти поля, если они
> по умолчанию и так уже равны False, что вполне логично
Не по умолчанию, а при создании. Т.е. это заслуга не
конструктора, а, скажем, InitInstance.
Но, при повторном вызове Create и не требуется оный вызов
(иначе, весь его смысл пропадает).
Согласен, что случай этот весьма специфический, но,
именно в этом случае логичен вызов Thread.Create
(как неклассовый вызов). Ну, и с этим случаем борланды
не справились, хотя вполне были и в состоянии.
Например, достаточно было обратить переменные
состояния (на not), т.е., немного подумать
при проектировании этого класса.
--
Regards, LVT.
← →
Сергей М. © (2007-02-06 15:16) [14]
> Leonid Troyanovsky © (06.02.07 14:28) [13]
Что-то ты загнул)
Причем здесь FTerminated и FFinished, если к работе thread-объекта как ОС-объекта они не имеют ни малейшего отношения ?
← →
Leonid Troyanovsky © (2007-02-06 15:36) [15]
> Сергей М. © (06.02.07 15:16) [14]
> Причем здесь FTerminated и FFinished, если к работе thread-
> объекта как ОС-объекта они не имеют ни малейшего отношения
А я, вообще, ничего не говорил про ОС-объект.
Только про дельфийский.
--
Regards, LVT.
← →
Сергей М. © (2007-02-06 15:41) [16]
> Leonid Troyanovsky © (06.02.07 15:36) [15]
> Только про дельфийский.
Ну тогда речь у тебя должна была зайти, в 1-ю очередь, не про какие-то там FTerminated и FFinished, а про хендл (или ID) уже созданного треда как объекта ОС и его фигурировании в конструкторе треда как дельфийского объекта)
← →
iXT © (2007-02-06 16:18) [17]
> evvcom © (06.02.07 09:08) [6]
В принципе не причем. Но зачем держать в памяти ничего не делаюший поток. ИМХО поток нужен для выполнения "тяжелых" операций, дабы не загружать основной. Сделал свое "грязное дело" свободен, тобеж FREE. Пока нужен крутись в while. Понадобишся еще создадут заново.
Хотя конечно все от конкретной задачи зависит...
← →
RASkov (2007-02-06 16:24) [18]Спасибо всем ответившим.
Прочел все сообщения. Некоторые уточнения
> [8] Leonid Troyanovsky © (06.02.07 11:30)
> Формально должно было бы так: Thread.Create(..),
Т.е. так имелось ввидуvar T: Thread;
первый "старт"T:=Thread.Create(False);
второйT.Create(False);
??
> [9] Сергей М. © (06.02.07 11:34)
Ну так она же не в потоке выполнится, т.е. [7] вторая строка...
Извеняюсь, если ответы на эти уточнения уже озвучены сдесь, я их не увидел, сорри.
← →
Сергей М. © (2007-02-06 16:29) [19]
> Ну так она же не в потоке выполнится,
Кто "она" ?
← →
evvcom © (2007-02-06 16:44) [20]> [17] iXT © (06.02.07 16:18)
> Но зачем держать в памяти ничего не делаюший поток.
Поток или объект-обертку над ОС-потоком? ОС-поток и так умирает, а объект-обертка может потребоваться, чтобы получить какие-то результаты работы потока, и только потом этот объект может быть уничтожен. Так что не надо путать.
> [11] Leonid Troyanovsky © (06.02.07 12:49)
Я не вижу смысла в повторной инициализации TThread. Если он закончил работу, то пусть умрет, если временно закончились для него данные, пусть уснет. А только для того, чтобы а вдруг потребуется опять поток с таким же функционалом, ОС-поток убивать, а дельфи-объект держать, экономя на Destroy/Create, не вижу смысла. Имхо.
← →
Сергей М. © (2007-02-06 16:48) [21]
> evvcom © (06.02.07 16:44) [20]
Впрочем, некая доля разумного в идеях ЛТ есть.
Только не в форме Thread.Create-конструктора, а в форме некоего потенциально возможного метода Thread.ReCreate с соответствующими принципиальными коррекциями в самом классе TThread.
← →
evvcom © (2007-02-06 16:52) [22]> [21] Сергей М. © (06.02.07 16:48)
> Впрочем, некая доля разумного в идеях ЛТ есть.
Да я и не говорю, что разумного нет. Да, можно было сделать. Просто мне такого никогда не требовалось, может потому я и не вижу смысла. Потому я "ИМХО" и добавил.
> Thread.ReCreate
Тогда уж Initialize :)
← →
Сергей М. © (2007-02-06 16:55) [23]
> evvcom © (06.02.07 16:52) [22]
> Тогда уж Initialize :)
Да обзови его хоть горшком - лишь бы смысл был прозрачен)
← →
Leonid Troyanovsky © (2007-02-06 18:03) [24]
> Сергей М. © (06.02.07 15:41) [16]
> Ну тогда речь у тебя должна была зайти, в 1-ю очередь, не
> про какие-то там FTerminated и FFinished, а про хендл (или
> ID) уже созданного треда как объекта ОС и его фигурировании
> в конструкторе треда как дельфийского объекта)
С хендлом больших проблем нет, т.е. он среди public.
А вот с приватными полями - есть, их-то надо обнулить
при повторном вызове. Хотя, конечно, собака рылась
именно в FTerminated - для правильно построенных поточных
функций именно она воспрепятствует работе потока.
--
Regards, LVT.
← →
Leonid Troyanovsky © (2007-02-06 18:04) [25]
> RASkov (06.02.07 16:24) [18]
> второй
> T.Create(False);
Да.
--
Regards, LVT.
← →
Leonid Troyanovsky © (2007-02-06 18:09) [26]
> Сергей М. © (06.02.07 16:48) [21]
> Только не в форме Thread.Create-конструктора, а в форме
> некоего потенциально возможного метода Thread.ReCreate с
Пусть так. Но, препятствием на этом пути является приватность
того же FTerminated. Т.е., налицо - плохое проектирование класса.
Казалось бы, управление виндовыми сущностями, скажем,
окнами, таймерами и др. - давно и успешно освоенная тема.
--
Regards, LVT.
← →
Leonid Troyanovsky © (2007-02-06 18:12) [27]
> evvcom © (06.02.07 16:44) [20]
> для него данные, пусть уснет. А только для того, чтобы а
> вдруг потребуется опять поток с таким же функционалом, ОС-
> поток убивать, а дельфи-объект держать, экономя на Destroy/Create,
> не вижу смысла. Имхо.
А зачем тогда TThread? Требуемой функциональности легко
достичь простым BeginThread, IMHO.
--
Regards, LVT.
← →
Leonid Troyanovsky © (2007-02-06 18:24) [28]
> Leonid Troyanovsky © (06.02.07 18:12) [27]
> > поток убивать, а дельфи-объект держать, экономя на Destroy/Create,
Да и дело не только в экономии ресурсов.
Вот, например, TTimer. Мне нет никакого дела до того,
что при Enabled := False виндовый таймер уничтожается,
а при наоборот - создается.
Поток несколько более сложный объект чем таймер,
а из средств управления - породить и убить.
--
Regards, LVT.
← →
RASkov (2007-02-06 21:26) [29]> [19] Сергей М. © (06.02.07 16:29)
> Кто "она" ?
[5]> Надо не поток стартовать, а необходимую процедуру в потоке, тогда не будет и таких извратов
Ну так она же не в потоке выполнится, т.е.
> //но что, все-таки, имелось ввиду в [5]....?
> Если вызвать процедуру потока, то она выполнится в основном потоке, а не в созданном(том в котором она описана)....
??
> [25] Leonid Troyanovsky © (06.02.07 18:04)
Спасибо. А что если что нибудь так сделать:
construktor TMyThread.MyCreate(S: Bool);
begin
inherited Create(S);
K:=T.Create; //к примеру
///
end;
procedure TMyThread.Start(S: Bool);
begin
if Work then Exit;
inherited Create(S);
end;
?
← →
Leonid Troyanovsky © (2007-02-06 21:56) [30]
> RASkov (06.02.07 21:26) [29]
> Спасибо. А что если что нибудь так сделать:
Не. Положение не настолько критическое (просто,
позволил себе поворчать).
Во-первых, есть простодушное, но железобетонное: TThread.Create..Free.
Во-вторых, есть возможность держать поток (пул потоков) в ожидании запросов.
Ну, а, в-третьих, организовать собс-ную оболочку для потока не так уж
и сложно, т.к. функция потока принимает параметр, который может
быть, например, указателем на экземпляр класса (потока).
См. также исходники TThread.
--
Regards, LVT.
Страницы: 1 вся ветка
Текущий архив: 2007.02.25;
Скачать: CL | DM;
Память: 0.53 MB
Время: 0.062 c