![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как корректно прекратить поток? [D7, XP]
dkhristich © (2010-02-25 18:07:00)Раньше с потоками не сталкивался, потому возник вопрос...
Программа после нажатия кнопки "Старт" запускает поток в котором происходит обмен информации с устройством по com-порту и запись полученных данных в базу данных. Если в результате обмена с устройством произошла ошибка (получены данные не соответствующие протоколу или вообще не получены) необходимо вывести соответствующее сообщение и прекратить выполнение потока до следующего нажатия Старта.
также обмен должен прерываться при нажатии кнопки "Стоп".
Какой командой прекратить выполнение потока из самого потока, и какой из основного потока (если есть разница)?
KilkennyCat (2010-02-28 01:46:00) [1]
> что в программах, разработанных с помощью
> > современных языков,
современными программистами.
Германн (2010-02-28 00:50:00) [2]
> С другой стороны то, что в программах, разработанных с помощью
> современных языков, при возникновении исключений в доп.
> потоках не возникает никаких уведомлений, - также имеет
> определенные минусы.
+1001
Loginov Dmitry (2010-02-28 00:30:00) [3]
> Ясен же пень, что не единственный.
Ясен пень :)
Но лучше если бы был единственными :)
Варианты с ExitThread() (из другого потока) / TerminateThread() на практике в 99% случаев бесполезные, и чаще всего используются по неопытности.
>
> Ну, и прав был MS, когда необработанные исключения во вторичном
> потоке завершали весь процесс, а не только самоё кривое.
Это довольно жестоко :)
С другой стороны то, что в программах, разработанных с помощью современных языков, при возникновении исключений в доп. потоках не возникает никаких уведомлений, - также имеет определенные минусы.
Демо (2010-02-27 20:06:00) [4]
> dkhristich © (25.02.10 18:07)
Начни хотя бы с пояснения фразы
> Программа после нажатия кнопки "Старт" запускает поток
Что это означает?.
Программа может использовать оболочку (TThread) над системными нитями (Thread) или создавать нити напрямую, используюя WinApi32.
Какой способ ты используешь?
Демо (2010-02-27 20:02:00) [5]
> DVM © (27.02.10 14:55) [14]
> > Демо © (27.02.10 12:13) [13]> Ну так прибей поток TerminateThreadи
> получи утечку ресурсов?
Да автору какая разница?
Ему уже объяснили. Только бесполезно.
Хоть бы статейки почитал что-ли, чтобы принципы понять...
Leonid Troyanovsky (2010-02-27 16:58:00) [6]
> Loginov Dmitry © (26.02.10 22:54) [12]
> ЕДИНСТВЕННЫЙ способ завершить работу потока - выйти из потоковой
> функции.
Ясен же пень, что не единственный.
Единственный же корректный способ - дать ему завершиться самому
не прибегнув к трюкам вроде ExitThread.
Да, и с исключениями потоки не "на ты".
Ну, и прав был MS, когда необработанные исключения во вторичном
потоке завершали весь процесс, а не только самоё кривое.
--
Regards, LVT.
DVM (2010-02-27 14:58:00) [7]
> dkhristich © (26.02.10 10:35) [9]
> мне нужно нажатием кнопки расположенной на форме, в любой
> момент прекратить выполнение потоковой кроцедуры.
В потоковой процедуре у тебя что делается? Циклы там есть?
DVM (2010-02-27 14:55:00) [8]
> Демо © (27.02.10 12:13) [13]
> Ну так прибей поток TerminateThread
и получи утечку ресурсов?
Демо (2010-02-27 12:13:00) [9]
> и я так и не понял как прибить поток из основного потока
> (кнопкой стоп)
Ну так прибей поток TerminateThread + освободи объект - Free.
Loginov Dmitry (2010-02-26 22:54:00) [10]
> > if Terminated the Exit; while not terminated do ...
>
> наверно не совсем то. мне нужно нажатием кнопки расположенной
> на форме, в любой момент прекратить выполнение потоковой
> кроцедуры.
ЕДИНСТВЕННЫЙ способ завершить работу потока - выйти из потоковой функции. Вызвать Exit, либо дождаться, когда функция полностью выполнится, либо сделать ей raise Exception / Abort (с исключениями - внимательнее!)
При нажатии кнопки, расположенной на форме, следует установить какой-то признак (флаг, Terminate и т.д.), который рано или поздно должен быть проверен потоковой функцией.
Anatoly Podgoretsky (2010-02-26 11:03:00) [11]> dkhristich (26.02.2010 10:35:09) [9]
> мне нужно нажатием кнопки расположенной на форме, в любой момент прекратить выполнение потоковой кроцедуры.
Ну так и вызывай метод Terminate, а он уже установит данную переменную.
Anatoly Podgoretsky (2010-02-26 11:02:00) [12]> dkhristich (26.02.2010 10:35:09) [9]
Вот так и прекратить, с помощью Exit, только желательно использовать защищеные блоки try finally
dkhristich (2010-02-26 10:35:00) [13]
> смотря, что имеется в виду под "прибить"
совсем прибить, без возможности возобновления
> собственно, завершение потока происходит по окончании потоковой
> процедуры
это понятно, если все прошло без ошибок то так и происходит, а если из порта получено не то что ожидается, процедуру необходимо закончить принудительно. с этим понятно помогает Exit.
осталось понять как завершить, без возможности восстановления из основного потока.
> if Terminated the Exit; while not terminated do ...
наверно не совсем то. мне нужно нажатием кнопки расположенной на форме, в любой момент прекратить выполнение потоковой кроцедуры.
> Кстати неплохо бы показать код - как именно создается поток
вот так
procedure TForm1.goClick(Sender: TObject);
begin
if flsh then
begin
ReadCE:=TReadCE.Create(true);
ReadCE.FreeOnTerminate:=true;
ReadCE.Priority:=tpLower;
ReadCE.Resume;
end;
сама процедура потока
File-New-Thread Object
внутри читаю с порта и если что не так, то Exit.
procedure TForm1.stopClick(Sender: TObject);
begin
//ВОТ ТУТ ЧТО НАПИСАТЬ ЧТОБ ВЫПОЛНЕНИЕ ПРОЦЕДУРЫ ПОТОКА
//ПРЕКРАТИЛОСЬ
end;
dkhristich (2010-02-25 19:55:00) [14]Теперь понятно, спасибо за разъяснение!
Вася (2010-02-25 19:53:00) [15]
> как прибить поток
смотря, что имеется в виду под "прибить"
поток можно остановить, чтобы потом можно было его возобновить, или же завершить (собственно, завершение потока происходит по окончании потоковой процедуры)
Кстати неплохо бы показать код - как именно создается поток
Anatoly Podgoretsky (2010-02-25 19:48:00) [16]Внутри потока достаточно выйти из метода Execute
Для этого есть полезная перенная Terminated, ее можно устанавливать и из основного потока.
Типичное использование if Terminated the Exit; while not terminated do ...
Сергей М. (2010-02-25 19:45:00) [17]
> Какой командой прекратить выполнение потока из самого потока
В Паскале нет "команд".
Есть операторы.
Это раз.
Поток - это объект ОС.
Его "прекращением" "заведует" сама ОС.
Это два.
Если ты процедуре, реализованной на языке Паскаль, то оператор Exit делает именнго то что тебе нужно ВНЕ зависимости от того в каком потоке эта процедура исполняется.
Это три.
dkhristich (2010-02-25 19:19:00) [18]прочитал до конца, мало что понял...
задам вопрос по другому...
в потоке при обнаружении ошибки протокола я попробовал вызвать процедуру exitвроде работает, могут ли позже всплыть проблемы после такого завершения?
и я так и не понял как прибить поток из основного потока (кнопкой стоп)
ПС я не зря написал в "Начинающим"
12 (2010-02-25 18:34:00) [19]http://www.delphimaster.ru/cgi-bin/forum.pl?id=1266238962&n=0
читать всю ветку
dkhristich (2010-02-25 18:25:00) [20]не нашел :(
если не тяжело, по подробнее...