Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Проблема с уничтожением TThread


Автор: pethead 1.6.2009, 18:36
забавная штука. вот есть у меня в одном классе внутрений thread.
если его не трогать а просто создать и перевести в спячку то он дестроится быстро. а если его запустить и там он что то покрутит какой то процесс, то потом снова перевести в спячку, топосле этого он дестроится неприлично долго.
среда дельфи6.

итак есть класс, в его креатере код:

fPollThread:=TPollThread.Create(True);// т.е. Suspend:=True - стоим ничего не делаем
fPollThread.FreeOnTerminate:=False;
fPollThread.Delay:=100;
fPollThread.OnPoll:=OnPoll;

далее где то в программе OnPoll
активизируется (или не активизируется) этот поток, т.е. в нем начинает крутится процедура OnPoll
потом где то там в программе поток деактивируется в Suspend.

в конце работы программы все уничтожается.
(все потоки заведомо переведены в Suspend!)

код деструктора класса

fPollThread.OnPoll:=nil;
fPollThread.Terminate;
FreeAndnil(fPollThread);//здесь существенная задержка если однажды поток был Resumed

выяснил что в момент  FreeAndnil(fPollThread) еще раз отрабатывается OnExecute. 
в Execute вызывается OnPoll но т.к. он уже =nil то ничего полезного не делается.

странно... хотя поток в Suspend.




Автор: kami 1.6.2009, 19:21
Цитата(pethead @  1.6.2009,  18:36 Найти цитируемый пост)
выяснил что в момент  FreeAndnil(fPollThread) еще раз отрабатывается OnExecute. в Execute вызывается OnPoll но т.к. он уже =nil то ничего полезного не делается.странно... хотя поток в Suspend.


Ничего странного.
Нужно только посмотреть исходники.
Код

if (FThreadID <> 0) and not FFinished then
  begin
    Terminate;
    if FCreateSuspended then // а вот и ответ на этот сложный вопрос.
      Resume;
    WaitFor;
  end;

Автор: pethead 1.6.2009, 20:04
а какой в этом смысл?

щас у меня написано так что создается всегда но не запускается. запускается по нужде потом. но зато и лишний раз резюмится при уничтожении.

похоже мне надо так написать код чтобы при нужде что то выполнить в потоке поток бы создавался сразу и запускался (CreateSuspend:=False)
а при прекращении нужды поток убивать.


Автор: kami 1.6.2009, 20:29
Цитата(pethead @  1.6.2009,  20:04 Найти цитируемый пост)
ведь уже все терминировано и мне этот вызов только усложняет жизнь.

Это знаете вы.
Но этого не знает компилятор.
Причина проста: не буду говорить за всех, но весь код инициализации (особенно - потокозависимых полей) я размещаю в Execute потока. И финализации тоже.
Поток же может быть заснут в любом состоянии. И если терминировать его  не разбудив - кто высвободит занятые в инициализации ресурсы?

Автор: pethead 1.6.2009, 20:36
Цитата(kami @  1.6.2009,  20:29 Найти цитируемый пост)
И если терминировать его  не разбудив - кто высвободит занятые в инициализации ресурсы? 
 кажись понял.

Автор: pethead 8.6.2009, 08:20
deleted

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)