![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как корректно удалить экземпляр TThread из TList? [D7]
kotyara12 © (2010-05-12 21:22:00)Может и друрацкий вопрос, но я уже совсем запутался: я создаю несколько независимых потоков с FreeOnTerminate = True и помещаю их в экземпляр TList. Что произойдет, если поток отработает до конца и удалиться из памяти? Произойдет ли при этом удаление соответствущего указателя из TList или нужно как-то по другому удалить отработавший поток?
RWolf (2010-05-13 15:53:00) [21]и ещё интересен момент — кем и как будут завершаться эти созданные и забытые потоки при закрытии приложения?
DVM (2010-05-13 15:53:00) [22]
> Вот тебе пример - нить делает NtQueryObject на синхронном
> > пайпе - я посмотрю как ты корректно завершишь такую нить.
Я сталкивался с аналогичной ситуацией, только были не пайпы, а сокеты в блокирующем режиме. Поток висел на connect() по 20 секунд и не было никакой возможности прервать поток.
Тогда же я на этом форуме высказал предположение о том, а хорошо ли будет использовать TerminateThread для быстрого выхода из приложения и прибивания таких потоков. Моментально был обруган уже не помню кем.
В результате был "изобретен" неблокирующий connect() для блокирующих сокетов.
Можно и в тупом цикле зависнуть - это не оправдание.
RWolf (2010-05-13 15:51:00) [23]> Rouse_ © (13.05.10 10:25) [66]
> Даже при включенном FreeOnTerminate мы спокойно выполняем
> первый и второй пункты.
каким образом, кстати?
экземпляры класса TMySuddenlyTerminatingThread могут стать недоступны в любой момент, значит, как-то по-другому; а как?
DVM (2010-05-13 15:44:00) [24]
> Rouse_ © (13.05.10 10:25) [66]
> А третий пункт вообще ни о чем.
Третий пункт как раз на случай завершения приложения - проходим по списку убиваем.
> Rouse_ © (13.05.10 10:25) [66]
> Вот тебе пример - нить делает NtQueryObject на синхронном
> пайпе - я посмотрю как ты корректно завершишь такую нить.
>
Так эта...может в архитектуре надо что-то подправить, чем разбрасываться TerminateThread?
DVM (2010-05-13 15:41:00) [25]
> Rouse_ © (13.05.10 10:25) [66]
> Даже при включенном FreeOnTerminate мы спокойно выполняем
> первый и второй пункты.
Выполнять то выполняем, но не кажется ли что при этом теряется все преимущество FreeOnTerminate := True - запустил и забыл?
Eraser (2010-05-13 13:57:00) [26]> [61] Leonid Troyanovsky © (13.05.10 07:42)
интересное замечание. когда-то давно были с этим грабли, по всей видимости из-за кривизны рук, но в мозгу отложился, как оказалось, ошибочный вывод, что нужно дожидаться окончания выполнения потока перед закрытием дескриптора. возможно теперь BeginThread будет использоваться чаще ;-)
Leonid Troyanovsky (2010-05-13 11:38:00) [27]
> Игорь Шевченко © (13.05.10 10:57) [67]
> - при завершении первичного потока вызывается не ExitThread,
> а ExitProcess
Если оную не вызвал вторичный поток ;)
--
Regards, LVT.
Игорь Шевченко (2010-05-13 10:57:00) [28]Leonid Troyanovsky © (13.05.10 07:57) [62]
> Это не всегда так. Попробуй пустить вторичный поток,
> а первичному сделать ExitThread.
В этом случае процесс не завершается. Но тут такой момент - при завершении первичного потока вызывается не ExitThread, а ExitProcess
Rouse_ (2010-05-13 10:25:00) [29]
> Loginov Dmitry © (12.05.10 23:45) [34]
> С того, что поток в этот момент занят записью какого-нибудь
> файла на жесткий диск.
И чего? Ты что не знаешь какой у тебя поток что делает и какой из них можно спокойно терминировать, а какой гарантированно висит в дедлоке? Ну-ну.
Если ПО чего-то пишет там на диск причем так, что при выключении компа оно не вырубается и мешает нормальной перезагрузке машины (ну пишет-же, чего его тревожат), то мне абсолютно пофиг на мнение разработчика данного ПО о корректности применения терминирования нити через АПИ ибо он моментально переносится в разряд криворуких и само ПО сносится с машины как класс. Помниться устанавливал я на свои машину парочку таких экземпляров - все в итоге оказались в корзине.
> DVM © (13.05.10 00:07) [39]
> 1) Мы всегда знаем, сколько у нас живых экземляров объекта
> TThread
> 2) Мы всегда можем быть уверены в том что в конкретный момент
> конкретный экземпляр жив.
> 3) Мы можем корректно закрыть все ресурсы потоков и сами
> потоки и затем уничтожить объекты TThread просто вызовом
> Terminate и WaitFor.
Чушь. Даже при включенном FreeOnTerminate мы спокойно выполняем первый и второй пункты. А третий пункт вообще ни о чем. Вот тебе пример - нить делает NtQueryObject на синхронном пайпе - я посмотрю как ты корректно завершишь такую нить.
> Лучше бы кто нибудь мне привел реальную пользу от FreeOnTerminate
А реальную пользу я тебе написал еще в [10], но ты по всей видимости пропустил этот момент.
Leonid Troyanovsky (2010-05-13 08:07:00) [30]
> kotyara12 (13.05.10 00:29) [53]
> к тому же пул нужно еще разобраться как реализовать
http://rsdn.ru/?article/baseserv/threadpool.xml
И еще статью by Alex Fedotov
http://rsdn.ru/?summary/2393.xml
--
Regards, LVT.
Leonid Troyanovsky (2010-05-13 08:01:00) [31]
> Loginov Dmitry © (12.05.10 23:35) [27]
> Лобовой метод обхода
Военная мудрость? :)
--
Regards, LVT.
Leonid Troyanovsky (2010-05-13 07:59:00) [32]
> Rouse_ © (12.05.10 23:31) [20]
> Имеется ввиду через апи TerminateThread()
Чего мелочиться: TerminateProcess.
--
Regards, LVT.
Leonid Troyanovsky (2010-05-13 07:57:00) [33]
> Игорь Шевченко © (13.05.10 00:44) [56]
> Как ты понимаешь, при завершении первичного потока процесса,
Это не всегда так. Попробуй пустить вторичный поток,
а первичному сделать ExitThread.
У Рихтера, да и в мсдн, есть условия завершения процесса (лень искать).
Одно из них: завершение при завершении последнего потока, ЕМНИП.
--
Regards, LVT.
Leonid Troyanovsky (2010-05-13 07:42:00) [34]
> Eraser © (12.05.10 23:23) [13]
> кстати, всегда интересовал такой вопрос - где правильно
> уничтожать дескриптор созданного через Begin/CreateThread
> потока? )
Тогда, когда хендл стал более не нужен.
Можно хоть сразу после BeginThread.
--
Regards, LVT.
Leonid Troyanovsky (2010-05-13 07:33:00) [35]
> antonn © (12.05.10 23:18) [11]
> там Synchronize() случаем не нужен?
The OnTerminate event handler is called in the context of the main VCL thread
--
Regards, LVT.
Германн (2010-05-13 02:30:00) [36]
> sniknik © (13.05.10 02:15) [57]
>
> блин, во у вас тут пляски с бубном...
>
Тут, имхо, пляшут не только Фома с Ерёмой. Тут скорее хоровод группы, каждый из которой, пляшет свой танец.
Но у всех них есть общее. Они пляшут под музыку Дельфи.
Некоторые ещё умудряются плясать под две музыки сразу. Но жалуются на сложности такой пляски.
:)
sniknik (2010-05-13 02:18:00) [37]кстати пример потоков в дельфе (ну тот который пример сортировок) именно так и делает, насколько помню.
sniknik (2010-05-13 02:15:00) [38]блин, во у вас тут пляски с бубном...
если бы хотел уничтожить кучу потоков, с обязательным "своим" контролем, то сделал бы так
for i := 0 to Count - 1 do
Item[i].Terminate;
while ThreadCount > 0 do
Sleep(10);
for i := 0 to Count - 1 do
Item[i].Free
ну и, понятно в начале execute ThreadCount+1 в конце ThreadCount-1. и все.
мало того мороки меньше так еще и сработать в сумме должно быстрее, чем персональное ожидание завершения каждого потока (одному больше на это времени нужно другому меньше, так не "времена" не будут складываться, а будет примерно равно одному - максимальному).
Игорь Шевченко (2010-05-13 00:44:00) [39]DVM © (13.05.10 00:19) [45]
> Пока программа работает и закрываться не собирается. Но
> вот она собралась закругляться. И что у нас там летает контролировать
> сложно. Хорошо если оно там умрет своей смертью вовремя
> без последствий.
Как ты понимаешь, при завершении первичного потока процесса, автоматически завершаются все дополнительные потоки в этом процессе.
kotyara12 (2010-05-13 00:33:00) [40]ну да ладно, завтра продолжим "тренироваться".. еще раз всем спасибо...
зы: все равно дома sql базы нет - пробовать не на чем, а тестовый пример лепить лень.