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

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

Как корректно удалить экземпляр TThread из TList? [D7]


Страницы:   1 2 3 4 5

kotyara12 ©   (2010-05-12 21:22:00) 

Может и друрацкий вопрос, но я уже совсем запутался: я создаю несколько независимых потоков с FreeOnTerminate = True и помещаю их в экземпляр TList. Что произойдет, если поток отработает до конца и удалиться из памяти? Произойдет ли при этом удаление соответствущего указателя из TList или нужно как-то по другому удалить отработавший поток?


Loginov Dmitry   (2010-05-12 23:45:00) [61]


> > Убивать потоки принудительно через TerminateThread() недопустимо.
>
> >
>
> При завершении приложения? С чего бы это?


С того, что поток в этот момент занят записью какого-нибудь файла на жесткий диск. Убъешь поток, получишь пол-файла или вообще ничего.


DVM   (2010-05-12 23:42:00) [62]


> Rouse_ ©   (12.05.10 23:38) [30]


> При завершении приложения? С чего бы это?

Не, я не про завершение конечно. Хотя...
Я привык и при завершении пытаться все по-человечески все закрывать.


Loginov Dmitry   (2010-05-12 23:41:00) [63]


> Имеется ввиду через апи TerminateThread()


Превосходный совет, нет слов :)


> Проблема то не в самом FreeOnTerminate = True, а в том,
> что его применение без особой на то необходимости и без
> тщательного контроля происходящего принесет только проблемы.
>  Есть некоторая неочевидность того, что происходит при его
> применении и как пользоваться этим свойством.


Тут вроде как всего 2 варианта: либо мы ставим FreeOnTerminate = False, и отвечаем на уничтожение, либо ставим FreeOnTerminate = True, и дальше ни коем образом к объекту потока не обращаемся (ибо он может оказаться уничтожен в любой момент). Кстати да, есть поводы для глюков, как и со Suspend. Может подать идейку чтоб и FreeOnTerminate сделали deprecated =)


Rouse_   (2010-05-12 23:39:00) [64]


> Eraser ©   (12.05.10 23:37) [29]
> так и не чего синхронайз использовать, imho. за редчайшим
> исключением можно обойтись без него

Я бы кнечто тоже за, но ты реальзацию метода WaitFor смотрел? :)
Особливо вызов метода CheckSynchronize в рамках сервиса?


Rouse_   (2010-05-12 23:38:00) [65]


> DVM ©   (12.05.10 23:36) [28]
>
> Убивать потоки принудительно через TerminateThread() недопустимо.
>

При завершении приложения? С чего бы это?
И кстати, ты так и не привел аргументов в пользу отсутствия FreeOnTerminate


Eraser   (2010-05-12 23:37:00) [66]

> [26] DVM ©   (12.05.10 23:35)

кстати да, тут или FreeOnTerminate := true убрать, или WaitFor;


> [25] Rouse_ ©   (12.05.10 23:34)

так и не чего синхронайз использовать, imho. за редчайшим исключением можно обойтись без него и даже более грамотно выйдет.


DVM   (2010-05-12 23:36:00) [67]

Убивать потоки принудительно через TerminateThread() недопустимо.


Loginov Dmitry   (2010-05-12 23:35:00) [68]


> пробовал. наткнулся на следующие грабли: при останвке сервиса
> останавливаю все потоки задач:


Правильно зависает. Зато ведь понятно из-за чего!

Лобовой метод обхода:

with fTaskList.LockList do
begin
try
  for i := 0 to Count - 1 do
    TThread(Item[i]).Terminate;
finally
  fTaskList.UnlockList;
end
end;

while True do
begin
 with fTaskList.LockList do
 try
    ACount := Count;
 finally
   fTaskList.UnlockList;
 end;
 
 if ACount = 0 then
   Break
 else
 begin
   Sleep(10);
   //Application.ProcessMessages();
 end;
end;


DVM   (2010-05-12 23:35:00) [69]


> kotyara12   (12.05.10 23:27) [18]



> with fTaskList.LockList do
> begin
>  try
>    for i := 0 to Count - 1 do
>      TThread(Item[i]).Terminate;
>      TThread(Item[i]).WaitFor; <- ЗДЕСЬ ЗАВИСАЕТ НАМЕРТВО,
>  приходится снимать процесс
>  finally
>    fTaskList.UnlockList;
>  end
> end

Ты свое глюконосное FreeOnTerminate := true убери и не будет виснуть.


Rouse_   (2010-05-12 23:34:00) [70]


> дождаться завершения потока через WaitFor.

Не получиться опять-же, дедлок из-за неочевидного механизма синхронизаии в очень многих случаях :)


Eraser   (2010-05-12 23:33:00) [71]

> [18] kotyara12   (12.05.10 23:27)

OnTerminate срабатывает? где в этот момент висит TThread(Item[i])?


kotyara12   (2010-05-12 23:32:00) [72]


> Rouse_ ©   (12.05.10 23:31) [20]
> Имеется ввиду через апи TerminateThread()

спс... щас покопаемся...


Eraser   (2010-05-12 23:32:00) [73]

> [15] Rouse_ ©   (12.05.10 23:24)

да, и потому FreeOnTerminate наше все, т.к. частенько контроль этих самых дескрипторов выливается в куда более не тривиальную задачу, чем сам код потока.
а в случае чего всегда можно FreeOnTerminate отключить, убрать обработчик OnTerminate и дождаться завершения потока через WaitFor.

ну собственно я это не вам рассказываю, а топикстартеру )


DVM   (2010-05-12 23:31:00) [74]


> Rouse_ ©   (12.05.10 22:51) [7]


> Игорь Шевченко ©   (12.05.10 23:06) [8]

Аргументы чего я должен привести?

Проблема то не в самом FreeOnTerminate = True, а в том, что его применение без особой на то необходимости и без тщательного контроля происходящего принесет только проблемы. Есть некоторая неочевидность того, что происходит при его применении и как пользоваться этим свойством.


Rouse_   (2010-05-12 23:31:00) [75]

Имеется ввиду через апи TerminateThread()


Rouse_   (2010-05-12 23:30:00) [76]

В рамках сервиса так нельзя - будет дедлок. - Срывай через терминирование.


kotyara12   (2010-05-12 23:27:00) [77]


> Вместо TList в таких случаях следует использовать TThreadList

пробовал. наткнулся на следующие грабли: при останвке сервиса останавливаю все потоки задач:

with fTaskList.LockList do
begin
 try
   for i := 0 to Count - 1 do
     TThread(Item[i]).Terminate;
     TThread(Item[i]).WaitFor; <- ЗДЕСЬ ЗАВИСАЕТ НАМЕРТВО, приходится снимать процесс
 finally
   fTaskList.UnlockList;
 end
end


Rouse_   (2010-05-12 23:24:00) [78]


> kotyara12   (12.05.10 23:23) [14]
>
>
> > Rouse_ ©
>
> это как раз и есть сервис...

Тогда ололо - готовь голову к шишкам от граблей :)


Loginov Dmitry   (2010-05-12 23:24:00) [79]


> Что остается - остается только пресловутый FreeOnTerminate,
>  который позволяет нам не заморачиваться на написание кода
> типа WaitForSingleObject, а просто создать нить - передать
> ей задачу и забыть.


Вот-вот, передать задачу и забыть. И этом вся прелесть!


Rouse_   (2010-05-12 23:24:00) [80]


> Eraser ©   (12.05.10 23:23) [13]

Ествесвенно по завершении оного :)


Страницы:   1 2 3 4 5

Наверх

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