Текущий архив: 2005.07.11;
Скачать: CL | DM;
ВнизПрервать выполнение потока (TThread) Найти похожие ветки
← →
cheloveck (2005-05-14 09:52) [0]Работает поток продолжительное время и если закрыть программу до окончания работы потока то выходит ошибка (из потока формируется список TList
Synchronize(SynhroList)
). Что лучше: дожидаться выполнения потока или прервать?
А если прервать то как безопасно это сделать (с проверкой на существование потока)?
Поток создается, на каждый случай формирования списка, так:mFScaner := TFScaner.Create(True);
mFScaner.FreeOnTerminate := true;
mFScaner.Priority := tpNormal;
mFScaner.Resume;
← →
Style © (2005-05-14 09:56) [1]TerminateThread?
← →
Digitman © (2005-05-14 10:02) [2]
> Что лучше: дожидаться выполнения потока или прервать?
лучше если доп.поток самостоятельно завершит свое выполнение по команде основного потока.
а чтобы он это сделал как можно быстрее, в методе TThread.Execute можно циклически и как можно чаще проверять состояние флага TThread.Terminated (при создании доп.потока он сброшен и будет взведен как только какой-либо поток вызовет метод TThread.Terminate), и как только будет обнаружено взведенное состояние флага немедленно завершать выполнение цикла с последующим завершением работы TThread.Execute
← →
novice_man © (2005-05-14 10:08) [3]Digitman © (14.05.05 10:02) [2]
Как выполнить ожидание завершение потока в программе?
← →
Style © (2005-05-14 10:12) [4]Thread.Terminate;
Thread.WaitFor;
Thread.Free;
← →
novice_man © (2005-05-14 10:52) [5]спасибо
← →
Digitman © (2005-05-14 11:04) [6]
> novice_man © (14.05.05 10:08) [3]
пример в [4] c учетом FreeOnTerminate = True чреват "граблями".
ибо нет никакой гарантии, что на момент Thread.WaitFor объект еще существует - он вполне мог быть уже и уничтожен в период времени между Thread.Terminate и Thread.WaitFor
FreeOnTerminate = True в ряде его применений - опасный подход к уничтожению трэд-объектов
я бы рекомендовал не взводить этот флаг, а просто в нужный момент ЯВНО вызывать Thread.Free, при условии что алгоритм в теле Execute корректно реагирует на состояние флага Terminated
← →
Marser © (2005-05-14 11:58) [7]
> novice_man © (14.05.05 10:52) [5] [Новое
>сообщение][Ответить]
> спасибо
Нужно помнить, что Terminate всего лишь устанавливает Terminated. Обычно тело потока устроено так: repeat..until Terminated, то есть проверка и завершение произойдут только в конце текущей итерации цикла. Поэтотому нужно ввести в теле цикла дополнительную проверку вроде if Terminated then Exit
← →
Style © (2005-05-14 12:12) [8]
Digitman © (14.05.05 11:04) [6]
FreeOnTerminate = True в ряде его применений - опасный подход к уничтожению трэд-объектов
я бы рекомендовал не взводить этот флаг, а просто в нужный момент ЯВНО вызывать Thread.Free, при условии что алгоритм в теле Execute корректно реагирует на состояние флага Terminated
Что может быть опасного во FreeOnTerminate
все равно в итоге вызывается.
if FreeThread then Thread.Free;
Причем не из самого класса, а из глобальной процедуры потока???
← →
GuAV © (2005-05-14 14:07) [9]
> Что может быть опасного во FreeOnTerminate
То что после присвоения этого флага с переменной класса потока манипуляции [4] так же как и другие манипуляции могут привести к непредсказуемым последствиям, т.к. поток может сам себя освободить после завершения, а завершится он может уже до выполнения этих манипуляций.
Если в конструкторе потока св-ву FreeOnTerminate присваивается True, то не следует вообще объявлять переменную класса потока. Т.е. не Thread := TmyThd.Create; , а просто TmyThd.Create;
Разуеется, если поток гарантированно не завершится до выполнения определённого условия, то можно использовать переменную класса потока до выполнения этого условия, но imho проще не использовать FreeOnTerminate в этом случае.
← →
Digitman © (2005-05-14 14:22) [10]
> Что может быть опасного во FreeOnTerminate
сам по себе он нисколько не опасен.
но если требуется некий контроль за работой потока после его создания через его же методы, и при этом не приняты никакие меры по уведомлению о завершении потока, то схлопотать AV в какой-то момент времени при обращении к св-ву/методу уже несуществующего объекта (ведь он сам себя разрушает !) - это запросто
← →
evvcom © (2005-05-14 14:40) [11]
> Поэтотому нужно ввести в теле цикла дополнительную проверку
> вроде if Terminated then Exit
Ты забыл упомянуть несколько "если". В общем случае ЭТО совершенно не обязательно.
← →
Style © (2005-05-14 14:44) [12]
> сам по себе он нисколько не опасен.
> но если требуется некий контроль за работой потока после
> его создания через его же методы, и при этом не приняты
> никакие меры по уведомлению о завершении потока, то схлопотать
> AV в какой-то момент времени при обращении к св-ву/методу
> уже несуществующего объекта (ведь он сам себя разрушает
> !) - это запросто
Но это уже называется дикий указатель...
С таким же успехом можно убить поток и из какого-нибудь другого потока. А в треьем обратиться к указателю на уже не существующий, что возможно приведет к AV.
← →
Marser © (2005-05-14 14:48) [13]
> evvcom © (14.05.05 14:40) [11] [Новое
>сообщение][Ответить]
>
> > Поэтотому нужно ввести в теле цикла дополнительную
>проверку
>> вроде if Terminated then Exit
>
> Ты забыл упомянуть несколько "если". В общем случае
> ЭТО совершенно не обязательно.
Ага. Только общий перерастает в частный частенько просто незаметно. Как однажды вышло у меня... Потому я и обратил внимание на причину этого - стандартная проверка в конце текущей итерации.
Страницы: 1 вся ветка
Текущий архив: 2005.07.11;
Скачать: CL | DM;
Память: 0.48 MB
Время: 0.047 c