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

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

TerminateThread - почему не работает? [D7, Win2k]


w666w ©   (2003-09-30 12:29:00) 

Объясните плиз, почему может не выполнятся TerminateThread для потока? GetLastError также не хранит никакого кода ошибки, поэтому понять суть происходящего я вообще не могу :(. Читал, что в Win2000 для выполнения этой процедуры поток должен иметь права на уничтожение THREAD_TERMINATE, но как эти права выставлять? И кем?

Как правильно вызывать этот метод? С каким кодом dwExitCode (и вообще какие они бывают и для чего). Нужно ли приостанавливать поток (Suspend) перед вызовом TerminateThread и влияет ли это как нибудь на вызов этой функции или нет? Как вручную очистить память после уничтожения потока при TerminateThread и т.п.

Заранее спасибо!


Digitman   (2003-09-30 14:51:00) [1]

даже в случае с IcmpSendEcho(), где гнездо явно не создается, можно использовать асинхронный режим ... на то и код статуса соответствующий имеется - IO_PENDING. Т.е. всесто блокирующей операции нужно инициировать overlapped-операцию, тогда IcmpSendEcho() на время своего выполнения не будет блокировать вызвавший ее код.поток


Verg   (2003-09-30 14:46:00) [2]

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

Пока только такие мысли...


Verg   (2003-09-30 14:40:00) [3]

Ага, понятно, блокирующие сокеты.

А что WSAEventSelect в Indy не применяется?

P.S. И все же, а почему был вынесен такой"диагноз" - не работает TerminateThread?


likeanangel   (2003-09-30 13:56:00) [4]

Тебе нужно сделать в каждой поточной функции вызов проверки существования некоторого объекта-флага (OpenMutex подойдет). В случае его существования выходи из поточной функции , иначе продолжай выполнение. Перед завершение приложения создай этот объект: CreateMutex(). В конце не забудь про ReleaseMutex().


Digitman   (2003-09-30 13:51:00) [5]


> для прерывания


да не надо ничего "прерывать" !

ты имеешь хоть малейшее понятие об асинхронных операциях ввода/вывода ? о различии асинхронных и синхронных (читай - неблокирующих и неблокирующих) операций ?


FireHack   (2003-09-30 13:50:00) [6]

если у тебя W2k, то при завершении процесса его потоки уничтожаются автоматически. Но, как правильно сказал likeanangel, такое программирование - плохой пример.

естественным путем обрубить поток у меня не получается

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


w666w   (2003-09-30 13:42:00) [7]

Digitman [11]

Спасибо за наводку, но я не понял, о чем речь. Вы не могли бы привести хоть какой-нить кусок кода, например для прерывания IcmpSendEcho или connect, происходящими на данный момент в потоке. Очень нужно.


Digitman   (2003-09-30 13:38:00) [8]

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


w666w   (2003-09-30 13:30:00) [9]

Ваша ирония вполне понятна, но по сути вопроса к сожалению никто так и не высказался...

В двух словах тяжело объяснить, почему тяжело уничтожить поток естественным путем, но все же:

каждый поток реализует 4 действия:
1. idHTTP.Post
2. IcmpSendEcho
3. connect(params)
4. gethostbyaddr(params)

каждое из этих действий "замораживает" поток на определенный Timeout (необходимый для завершения текущей операции). Вот в тот момент, когда приложение необходимо закрыть, неизвестно, что в данный момент делает тот или иной поток. Потоков более 1000, их контролирует поток-мастер. Представьте, какую необходимо делать обработку для нормального завершения потоков. Более того, я не имею представления, каким образом прервать, допустим, gethostbyaddr. Если в Случае с idHTTP можно сделать idHTTP.Disconnect для моментального обрыва соединения, то как быть с gethostbyaddr? А закрывать сокеты при connect или ping?

Более того, эту обработку возможно выполнить, скажем для 1 потока. Но пока эта обработка производится, большинство других потоков уже отработали и возникает проблема определения их существования. Хорошо, поместим цикл обработки всех потоков в try..finally..end. Но для чего весь этот гемор, если винда перегружается и мне необходимо МОМЕНТАЛЬНО ОТРУБИТЬ ВСЕ ПОТОКИ без сохранения каких либо данных и т.д.?


Digitman   (2003-09-30 13:15:00) [10]


> естественным путем обрубить поток у меня не получается


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


N169   (2003-09-30 13:13:00) [11]

А может коллега объект типа TThread уничтожает с помощью CloseHandle()? :)


Verg   (2003-09-30 13:07:00) [12]


> Объясните плиз, почему может не выполнятся TerminateThread
> для потока


Откуда ты знаешь, что он не выполнился?

А вообще вот это читал?

Terminating a thread does not necessarily remove the thread object from the system. A thread object is deleted when the last thread handle is closed.


Игорь Шевченко   (2003-09-30 13:05:00) [13]

w666w (30.09.03 12:54)

http://msdn.microsoft.com


Verg   (2003-09-30 13:02:00) [14]


> К сожалению естественным путем обрубить поток у меня не
> получается, нужен именно TT.


Ну, пока что у тебя и с ТТ не получается. Так может все же лучше со стороны легального завершения потока подойти, раз пока все равно с какой?


w666w   (2003-09-30 12:59:00) [15]

DLL я в проекте не использую, а вот моментальное уничтожение потоков при выходе из программы ООЧЕНЬ необходимо. К сожалению естественным путем обрубить поток у меня не получается, нужен именно TT.


likeanangel   (2003-09-30 12:56:00) [16]

А ты уверен, что тебе нужен именно TerminateThread() ?! Вобщем-то, это достаточно скользкий тип программирования, потому что при вызове этой функции могут остаться какие-то аллоцированные ресурсы, хэндлеры, какие-то библиотеки не получат DLL_THREAD_DETACH и т.д. Гораздо разумнее завершить функцию потока естественным путем.


w666w   (2003-09-30 12:54:00) [17]

В том то и дело, что в help"е про TerminateThread вообще ни одной строчки нет :(. По крайней мере в D7 Enterprise


Игорь Шевченко   (2003-09-30 12:45:00) [18]

А help почитать не судьба ? Или опять тестирование телепатических способностей ?


Наверх

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