Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Прервать выполнение потока (TThread) [D6, WinXP]


cheloveck ©   (2005-05-14 09:52:00) 

Работает поток продолжительное время и если закрыть программу до окончания работы потока то выходит ошибка (из потока формируется список TList Synchronize(SynhroList)). Что лучше: дожидаться выполнения потока или прервать?
А если прервать то как безопасно это сделать (с проверкой на существование потока)?

Поток создается, на каждый случай формирования списка, так:
mFScaner := TFScaner.Create(True);
mFScaner.FreeOnTerminate := true;
mFScaner.Priority := tpNormal;
mFScaner.Resume;


Marser   (2005-05-14 14:48:00) [1]


> evvcom ©   (14.05.05 14:40) [11] [Новое
>сообщение][Ответить]
>
> > Поэтотому нужно ввести в теле цикла дополнительную
>проверку
>> вроде if Terminated then Exit
>
> Ты забыл упомянуть несколько "если". В общем случае
> ЭТО совершенно не обязательно.

Ага. Только общий перерастает в частный  частенько просто незаметно. Как однажды вышло у меня... Потому я и обратил внимание на причину этого - стандартная проверка в конце текущей итерации.


Style   (2005-05-14 14:44:00) [2]


> сам по себе он нисколько не опасен.
> но если требуется некий контроль за работой потока после
> его создания через его же методы, и при этом не приняты
> никакие меры по уведомлению о завершении потока, то схлопотать
> AV в какой-то момент времени при обращении к св-ву/методу
> уже несуществующего объекта (ведь он сам себя разрушает
> !) - это запросто


Но это уже называется дикий указатель...
С таким же успехом можно убить поток и из какого-нибудь другого потока. А в треьем обратиться к указателю на уже не существующий, что возможно приведет к AV.


evvcom   (2005-05-14 14:40:00) [3]


> Поэтотому нужно ввести в теле цикла дополнительную проверку
> вроде if Terminated then Exit

Ты забыл упомянуть несколько "если". В общем случае ЭТО совершенно не обязательно.


Digitman   (2005-05-14 14:22:00) [4]


> Что может быть опасного во FreeOnTerminate


сам по себе он нисколько не опасен.
но если требуется некий контроль за работой потока после его создания через его же методы, и при этом не приняты никакие меры по уведомлению о завершении потока, то схлопотать AV в какой-то момент времени при обращении к св-ву/методу уже несуществующего объекта (ведь он сам себя разрушает !) - это запросто


GuAV   (2005-05-14 14:07:00) [5]


> Что может быть опасного во FreeOnTerminate

То что после присвоения этого флага с переменной класса потока манипуляции [4] так же как и другие манипуляции могут привести к непредсказуемым последствиям, т.к. поток может сам себя освободить после завершения, а завершится он может уже до выполнения этих манипуляций.

Если в конструкторе потока св-ву FreeOnTerminate присваивается True, то не следует вообще объявлять переменную класса потока. Т.е. не Thread := TmyThd.Create; , а просто TmyThd.Create;

Разуеется, если поток гарантированно не завершится до выполнения определённого условия, то можно использовать переменную класса потока до выполнения этого условия, но imho проще не использовать FreeOnTerminate в этом случае.


Style   (2005-05-14 12:12:00) [6]


Digitman ©   (14.05.05 11:04) [6]

FreeOnTerminate = True в ряде его применений - опасный подход к уничтожению трэд-объектов

я бы рекомендовал не взводить этот флаг, а просто в нужный момент ЯВНО вызывать Thread.Free, при условии что алгоритм в теле Execute корректно реагирует на состояние флага Terminated


Что может быть опасного во FreeOnTerminate
все равно в итоге вызывается.
if FreeThread then Thread.Free;
Причем не из самого класса, а из глобальной процедуры потока???


Marser   (2005-05-14 11:58:00) [7]


> novice_man ©   (14.05.05 10:52) [5] [Новое
>сообщение][Ответить]
> спасибо

Нужно помнить, что Terminate всего лишь устанавливает Terminated. Обычно тело потока устроено так: repeat..until Terminated, то есть проверка и завершение произойдут только в конце текущей итерации цикла. Поэтотому нужно ввести в теле цикла дополнительную проверку вроде if Terminated then Exit


Digitman   (2005-05-14 11:04:00) [8]


> novice_man ©   (14.05.05 10:08) [3]


пример в [4] c учетом FreeOnTerminate = True чреват "граблями".

ибо нет никакой гарантии, что на момент Thread.WaitFor объект еще существует - он вполне мог быть уже и уничтожен в период времени между Thread.Terminate и Thread.WaitFor

FreeOnTerminate = True в ряде его применений - опасный подход к уничтожению трэд-объектов

я бы рекомендовал не взводить этот флаг, а просто в нужный момент ЯВНО вызывать Thread.Free, при условии что алгоритм в теле Execute корректно реагирует на состояние флага Terminated


novice_man   (2005-05-14 10:52:00) [9]

спасибо


Style   (2005-05-14 10:12:00) [10]

Thread.Terminate;
Thread.WaitFor;
Thread.Free;


novice_man   (2005-05-14 10:08:00) [11]

Digitman ©   (14.05.05 10:02) [2]
Как выполнить ожидание завершение потока в программе?


Digitman   (2005-05-14 10:02:00) [12]


> Что лучше: дожидаться выполнения потока или прервать?


лучше если доп.поток самостоятельно завершит свое выполнение по команде основного потока.
а чтобы он это сделал как можно быстрее, в методе TThread.Execute можно циклически и как можно чаще проверять состояние флага TThread.Terminated (при создании доп.потока он сброшен и будет взведен как только какой-либо поток вызовет метод TThread.Terminate), и как только будет обнаружено взведенное состояние флага немедленно завершать выполнение цикла с последующим завершением работы TThread.Execute


Style   (2005-05-14 09:56:00) [13]

TerminateThread?


Наверх

Титульная страница Поиск, карта сайта Написать письмо