Страница 2 из 2
Добавлено: 04 окт 2004, 10:55
Dragonfly
AiK, я так понимаю, что если ты создаешь окно в потоке, то так оно и надо (никогда не писал ничего для IE - это реализуется в виде модуля?), но ты уверен, что поток обязательно нужно убивать? Насколько я помню, в подобных случаях, т.е. например при постоянном прослушивании порта, сокета и т.п., я делал так:
void ThreadProc()
{
SetThreadPriority(...);
while(1)
{
}
}
Синтаксис функций не помню точно, сейчас под Linux?ом сижу и MSDN у меня тут нет
Т.е. даже если, как я предполагаю, IE сам поток создает, а потом его не убивает до конца своего существования, то можно воспользоваться тем же недостатком - Винда ведь сама все почистит?
Добавлено: 04 окт 2004, 13:49
AiK
Dragonfly, суть такая - я изначально неправильно стал делать поток. У меня таких потоков последовательно не один десяток будет вызываться, а окно должно быть одно. Так что окно буду создавать в другом потоке, а в этом потоке только данные, связанные с окном обновлять. А вот поток прибивать хотелось бы корректно. Под какой-то виндой можно всего навсего 40 потоков заводить, так что хендлы закрывать придётся. Пока ещё не придумал как. Что-то мне подсказывает, что если в конце ThreadProc вызвать GetCurrentThread, а потом CloseHandle, то ожидаемого эффекта я не получу... Короче, я временно забил на эту задачу - надо теорию поштудировать, а пока времени на это нет

Добавлено: 04 окт 2004, 14:36
Dragonfly
В принципе TerminateThread() вполне корректно убивает поток (с точки зрения системы) если поток в это время не активен. Т.е. запускаешь Sleep(2000) и как-то отмечаешь это состояние "для внешнего мира". Но я вызывал TerminateThread() только из родительского потока.
Добавлено: 04 окт 2004, 17:00
Eugie
В принципе TerminateThread() вполне корректно убивает поток (с точки зрения системы) если поток в это время не активен.
Вообще-то, TerminateThread() не рекомендуется использовать абы где, т.к. поток она убивает не вполне корректно (в частности, при этом не оповещаются DLL, загруженные в адр.пр-во процесса, не освобождаются некоторые системные ресурсы). Как написано в MSND, использовать ее следует только в
исключительных обстоятельствах.
AiK, вообще завершение потока возможно 2 способами: 1) его ThreadProc() завершила свою работу, вызвав return или ExitThread(); 2) поток извне 'попросили' завершиться (например, с помощью TerminateThread). Во втором случае корректная схема должна быть такая: перед созданием потока создаем объект
событие (см. CreateEvent), устанавливаем его в несигнальное состояние, посылаем его хэндл 4-м параметром в CreateThread и отслеживаем его состояние с помощью WaitForSingleObject: если состояние сигнальное, вызываем ExitThread. Конечно, по завершении потока его хэндл должен быть освобожден вызовом CloseHandle().
Еще одно замечание: если в потоковой процедуре будут использоваться CRT функции, следует создавать/завершать поток с помощью _beginthreadex()/_endthread().
Добавлено: 18 ноя 2004, 23:47
Kerghan
Знач так.
1. Никаких TerminateThread'ов, так как не освобождается стек потока и не только он.
2. Окна действительно принадлежат потокам, так как в контексте потока находтся все месаги этим окнам, и вслучае смерти потока, окна тоже помирают.
3. Вызывая GetCurrentThread мы получаем псевдо-хэндл. Закрывай его или не закрывай - мало что изменится.
4. СРАЗУ после вызова ht =CreateThread(....) нужно вызывать CloseHandle(ht) - поток это не прибьет, но уменьшится счетчик юзеров потока на 1. Это если не будут потом юзаться различные Wait-ф-ции конечно или SuspendThread. Просто вряд ли хэндл еще понадобится, а забыть его освободить всегда можна, и при завершении потока объект ядра останется до тех пор, пока не завершится весь процесс.
5. Корректно завершить поток можно следующим образом: у нас ведь есть окно. Вот и послать в случае необходимости этому окну какое-то сообщение; в обработчике же можна почиститься и вызвать ExitThread.
Добавлено: 19 ноя 2004, 16:36
Eugie
Kerghan, окно есть только в главном потоке. Поэтому вариант с сообщениями не годится. В данном случае (все потоки в АП одного процесса) можно сделать совсем просто - глобальный массив флагов. Запустил вторичный поток - установил флаг. Надо завершить - сбросил, а в потоковой процедуре отслеживать и вызывать ExitThread.