Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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.5 MB
Время: 0.038 c
3-1117369737
Erich
2005-05-29 16:28
2005.07.11
Ошибка при выполнении SQL запроса.


14-1118405411
Igorek
2005-06-10 16:10
2005.07.11
..кратии, ..кратии


5-1089896672
Domkrat
2004-07-15 17:04
2005.07.11
PReport


4-1116042693
КиТаЯц
2005-05-14 07:51
2005.07.11
Драйвер принтера (установлен ли?)


14-1118861856
yaJohn
2005-06-15 22:57
2005.07.11
хостинг с условиями