![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как корректно удалить экземпляр TThread из TList? [D7]
kotyara12 © (2010-05-12 21:22:00)Может и друрацкий вопрос, но я уже совсем запутался: я создаю несколько независимых потоков с FreeOnTerminate = True и помещаю их в экземпляр TList. Что произойдет, если поток отработает до конца и удалиться из памяти? Произойдет ли при этом удаление соответствущего указателя из TList или нужно как-то по другому удалить отработавший поток?
RWolf (2010-05-13 17:20:00) [1][93]
спасибо, прочитаю.
Rouse_ (2010-05-13 17:13:00) [2]
> RWolf © (13.05.10 17:07) [92]
> Если все висят, то такое приложение завершить можно только
> через диспетчер задач. Какая-то выделенная нить должна бодрствовать
> и ждать сигналов.
Это и есть главная нить службы - но она не бодрствует а находится в суспенде. Мехянику работы сервисов можешь почерпнуть вот из этого талмуда :)
http://rouse.drkb.ru/books.php#rihter1
RWolf (2010-05-13 17:07:00) [3]
> А когда наступит завершение, если все три нити висят? :)
Если все висят, то такое приложение завершить можно только через диспетчер задач. Какая-то выделенная нить должна бодрствовать и ждать сигналов.
Rouse_ (2010-05-13 17:04:00) [4]
> и вызовет событие TService.OnStop, где мы и завершим все
> свои потоки; или нет?
Да и какой TService - ты не внимательно читаешь - я же особо упоминал про не VCL сервис :)
Rouse_ (2010-05-13 17:03:00) [5]
> пусть висит — при завершении сервиса проснётся
А когда наступит завершение, если все три нити висят? :)
Игорь Шевченко (2010-05-13 17:02:00) [6]Значит, борландовских Demos недостаточно. Печально.
RWolf (2010-05-13 16:36:00) [7]
> при синхронизации с главной нитью АПИ сервиса - которая служит для общения с SCM и все время висит в суспенде.
пусть висит — при завершении сервиса проснётся и вызовет событие TService.OnStop, где мы и завершим все свои потоки; или нет?
Leonid Troyanovsky (2010-05-13 16:25:00) [8]
> RWolf © (13.05.10 16:18) [84]
> > И после этого входит в дедлок на функции thd.WaitFor.
> доступ к какому ресурсу вызывает этот дедлок?
Ну, тут раньше говорили про OnTerminate, в котором поток
удалял ссылку на себя из списка.
Николай, правда, показал как в этом случае надо поступить,
т.е., Terminate по списку и ждать пока список опустеет.
--
Regards, LVT.
Rouse_ (2010-05-13 16:21:00) [9]Т.е. главная нить - она на самом деле не главная. Для каждого сервиса в рамках процесса создается своя нить, причем если в рамках процесса крутиться два и более сервисов (SHARE флаг) то у каждого из них своя нить, а главная всегда висит.
Rouse_ (2010-05-13 16:19:00) [10]
> RWolf © (13.05.10 16:18) [84]
>
>
> > И после этого входит в дедлок на функции thd.WaitFor.
>
> доступ к какому ресурсу вызывает этот дедлок?
Пфф, ну я же уже раза три писал: при синхронизации с главной нитью АПИ сервиса - которая служит для общения с SCM и все время висит в суспенде.
RWolf (2010-05-13 16:18:00) [11]
> И после этого входит в дедлок на функции thd.WaitFor.
доступ к какому ресурсу вызывает этот дедлок?
имхо, всё прозрачно — поток осознал необходимость завершиться и вышел, при этом основной поток, ожидающий его хэндл в методе thd.WaitFor, получил управление.
Rouse_ (2010-05-13 16:15:00) [12]
> DVM © (13.05.10 16:13) [81]
> Я про VCL вообще то говорил.
VCL-ный не писал, там как раз должно быть нормально ибо вся эта ахинея с синхронизацией в отчасти как раз с огладкой на VCL-ный сервис и писалась.
А сделали бы по нормальному - синхронизация не с рутом, а с породившей нитью - вот бы сразу все шеколадно стало.
Rouse_ (2010-05-13 16:14:00) [13]
> RWolf © (13.05.10 16:09) [80]
> thd.Terminate;
> thd.Resume;
> //тут поток просыпается, видит, что его завершают, и выходит
> из Execute
> thd.WaitFor;
И после этого входит в дедлок на функции thd.WaitFor.
А по поводу MSDN - это все конечно хорошо, и то что ты читаешь сию справку - выше всяких похвал, но понимаешь в чем дело, есть множество ситуаций (пару которых я привел) в которых не обойтись никак без терминирования, о чем кстати писал в свое время Руссинович описывая решение проблемы с NtQueryObject
DVM (2010-05-13 16:13:00) [14]
> Rouse_ © (13.05.10 16:04) [78]
> http://rouse.drkb.ru/winapi.php#enumopenfiles
Будет время посмотрю :)
> Сервис конечно-же апишный ибо я про него говрю?
Я про VCL вообще то говорил.
RWolf (2010-05-13 16:09:00) [15]> Rouse_ © (13.05.10 15:59) [76]
> не убьеш ты в сервисе, зависнешь на попытке синхронизации
> с основным потоком который стоит в суспенде :)
thd.Terminate;
thd.Resume;
//тут поток просыпается, видит, что его завершают, и выходит из Execute
thd.WaitFor;
> остальное гораздо качественнее и прозрачнее делается через
> апи
то есть через TerminateThread?
Выдержка из MSDN:
TerminateThread is a dangerous function that should only be used in the most extreme cases. You should call TerminateThread only if you know exactly what the target thread is doing, and you control all of the code that the target thread could possibly be running at the time of the termination. For example, TerminateThread can result in the following problems:
* If the target thread owns a critical section, the critical section will not be released.
* If the target thread is allocating memory from the heap, the heap lock will not be released.
* If the target thread is executing certain kernel32 calls when it is terminated, the kernel32 state for the thread’s process could be inconsistent.
* If the target thread is manipulating the global state of a shared DLL, the state of the DLL could be destroyed, affecting other users of the DLL
Rouse_ (2010-05-13 16:06:00) [16]
> DVM © (13.05.10 16:03) [77]
> Хм. Я может чего то недопонимаю, но вот именно так я делал
> как то и ничего не висло.
Сервис конечно-же апишный ибо я про него говрю?
т.е. без использования всякого ненужно мусора в виде VCL-ного сервиса? :)
Rouse_ (2010-05-13 16:04:00) [17]
> DVM © (13.05.10 15:44) [71]
> Так эта...может в архитектуре надо что-то подправить, чем
> разбрасываться TerminateThread?
Не вопрос - я с радостью выслушаю предложение по доработке вот этого примера с пересмотром архитектуры :)
http://rouse.drkb.ru/winapi.php#enumopenfiles
DVM (2010-05-13 16:03:00) [18]
> Rouse_ © (13.05.10 15:59) [76]
> Ну не убьеш ты в сервисе, зависнешь на попытке синхронизации
> с основным потоком который стоит в суспенде :)
Хм. Я может чего то недопонимаю, но вот именно так я делал как то и ничего не висло.
Rouse_ (2010-05-13 15:59:00) [19]
> экземпляры класса TMySuddenlyTerminatingThread могут стать
> недоступны в любой момент, значит, как-то по-другому; а
> как?
Перекрывая соответствующий обработчик мы избежим ситуации что они станут недоступны в любой момент :)
> DVM © (13.05.10 15:44) [71]
> Третий пункт как раз на случай завершения приложения - проходим
> по списку убиваем.
Ну не убьеш ты в сервисе, зависнешь на попытке синхронизации с основным потоком который стоит в суспенде :)
> DVM © (13.05.10 15:41) [70]
> Выполнять то выполняем, но не кажется ли что при этом теряется
> все преимущество FreeOnTerminate := True - запустил и забыл?
Вот именно - это единственное преимущество данного класса - именно запустил и забыл, все остальное гораздо качественнее и прозрачнее делается через апи, поэтому я использую класс TThread именно только в таких случаях, когда мне не нужно контролировать время его никчемной жыздни :)
DVM (2010-05-13 15:54:00) [20]
> RWolf © (13.05.10 15:51) [72]
> значит, как-то по-другому; а как?
изобретаем синхронизированные велосипеды, о чем я и говорил. Смысл и преимущества все теряются.