Потоки (Threads) и окна.

Общие вопросы, не зависящие от языка реализации.

Модераторы: Duncon, Hawk, Romeo, Eugie

Dragonfly
Сообщения: 15
Зарегистрирован: 01 окт 2004, 18:23
Откуда: Киев

04 окт 2004, 10:55

AiK, я так понимаю, что если ты создаешь окно в потоке, то так оно и надо (никогда не писал ничего для IE - это реализуется в виде модуля?), но ты уверен, что поток обязательно нужно убивать? Насколько я помню, в подобных случаях, т.е. например при постоянном прослушивании порта, сокета и т.п., я делал так:

void ThreadProc()
{
SetThreadPriority(...);

while(1)
{
}
}

Синтаксис функций не помню точно, сейчас под Linux?ом сижу и MSDN у меня тут нет :)

Т.е. даже если, как я предполагаю, IE сам поток создает, а потом его не убивает до конца своего существования, то можно воспользоваться тем же недостатком - Винда ведь сама все почистит?
И накроет землю тень Армагеддона (и мы примем в этом активное участие :) )
Аватара пользователя
AiK
Сообщения: 2274
Зарегистрирован: 13 фев 2004, 18:14
Откуда: СПб
Контактная информация:

04 окт 2004, 13:49

Dragonfly, суть такая - я изначально неправильно стал делать поток. У меня таких потоков последовательно не один десяток будет вызываться, а окно должно быть одно. Так что окно буду создавать в другом потоке, а в этом потоке только данные, связанные с окном обновлять. А вот поток прибивать хотелось бы корректно. Под какой-то виндой можно всего навсего 40 потоков заводить, так что хендлы закрывать придётся. Пока ещё не придумал как. Что-то мне подсказывает, что если в конце ThreadProc вызвать GetCurrentThread, а потом CloseHandle, то ожидаемого эффекта я не получу... Короче, я временно забил на эту задачу - надо теорию поштудировать, а пока времени на это нет :(
Даже самый дурацкий замысел можно воплотить мастерски
Dragonfly
Сообщения: 15
Зарегистрирован: 01 окт 2004, 18:23
Откуда: Киев

04 окт 2004, 14:36

В принципе TerminateThread() вполне корректно убивает поток (с точки зрения системы) если поток в это время не активен. Т.е. запускаешь Sleep(2000) и как-то отмечаешь это состояние "для внешнего мира". Но я вызывал TerminateThread() только из родительского потока.
И накроет землю тень Армагеддона (и мы примем в этом активное участие :) )
Eugie
Сообщения: 707
Зарегистрирован: 17 фев 2004, 23:59
Откуда: SPb

04 окт 2004, 17:00

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

AiK, вообще завершение потока возможно 2 способами: 1) его ThreadProc() завершила свою работу, вызвав return или ExitThread(); 2) поток извне 'попросили' завершиться (например, с помощью TerminateThread). Во втором случае корректная схема должна быть такая: перед созданием потока создаем объект событие (см. CreateEvent), устанавливаем его в несигнальное состояние, посылаем его хэндл 4-м параметром в CreateThread и отслеживаем его состояние с помощью WaitForSingleObject: если состояние сигнальное, вызываем ExitThread. Конечно, по завершении потока его хэндл должен быть освобожден вызовом CloseHandle().

Еще одно замечание: если в потоковой процедуре будут использоваться CRT функции, следует создавать/завершать поток с помощью _beginthreadex()/_endthread().
Kerghan
Сообщения: 4
Зарегистрирован: 20 авг 2004, 23:39
Откуда: void
Контактная информация:

18 ноя 2004, 23:47

Знач так.
1. Никаких TerminateThread'ов, так как не освобождается стек потока и не только он.
2. Окна действительно принадлежат потокам, так как в контексте потока находтся все месаги этим окнам, и вслучае смерти потока, окна тоже помирают.
3. Вызывая GetCurrentThread мы получаем псевдо-хэндл. Закрывай его или не закрывай - мало что изменится.
4. СРАЗУ после вызова ht =CreateThread(....) нужно вызывать CloseHandle(ht) - поток это не прибьет, но уменьшится счетчик юзеров потока на 1. Это если не будут потом юзаться различные Wait-ф-ции конечно или SuspendThread. Просто вряд ли хэндл еще понадобится, а забыть его освободить всегда можна, и при завершении потока объект ядра останется до тех пор, пока не завершится весь процесс.
5. Корректно завершить поток можно следующим образом: у нас ведь есть окно. Вот и послать в случае необходимости этому окну какое-то сообщение; в обработчике же можна почиститься и вызвать ExitThread.
Eugie
Сообщения: 707
Зарегистрирован: 17 фев 2004, 23:59
Откуда: SPb

19 ноя 2004, 16:36

Kerghan, окно есть только в главном потоке. Поэтому вариант с сообщениями не годится. В данном случае (все потоки в АП одного процесса) можно сделать совсем просто - глобальный массив флагов. Запустил вторичный поток - установил флаг. Надо завершить - сбросил, а в потоковой процедуре отслеживать и вызывать ExitThread.
Ответить