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

Ответить

Код подтверждения
Введите код в точности так, как вы его видите. Регистр символов не имеет значения.

BBCode ВКЛЮЧЁН
[img] ВКЛЮЧЁН
[url] ВКЛЮЧЁН
Смайлики ОТКЛЮЧЕНЫ

Обзор темы
   

Развернуть Обзор темы: Потоки (Threads) и окна.

Eugie » 19 ноя 2004, 16:36

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

Kerghan » 18 ноя 2004, 23:47

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

Eugie » 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().

Dragonfly » 04 окт 2004, 14:36

В принципе TerminateThread() вполне корректно убивает поток (с точки зрения системы) если поток в это время не активен. Т.е. запускаешь Sleep(2000) и как-то отмечаешь это состояние "для внешнего мира". Но я вызывал TerminateThread() только из родительского потока.

AiK » 04 окт 2004, 13:49

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

Dragonfly » 04 окт 2004, 10:55

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

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

while(1)
{
}
}

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

Т.е. даже если, как я предполагаю, IE сам поток создает, а потом его не убивает до конца своего существования, то можно воспользоваться тем же недостатком - Винда ведь сама все почистит?

AiK » 02 окт 2004, 04:39

Dragonfly, прога сверхзловредная :) - это тулбар для IE. Так что вариант с драйвером не годится. CreateRemoteThread пробовал, разницы с CreateThread никакой не обнаружил. Похоже придётся с окном связывать данные и обновлять по мере получения в потоке...

Dragonfly » 01 окт 2004, 20:18

Можно. Я делал. Но нужны ОЧЕНЬ хорошие права. Для зловредных прог практически не подходит. Суть состоит в использовании CreateRemoteThread() можно создать свой поток хоть в kernel'е. Второй способ (описан или в том же Рихтере или в... а не помню). Называется "Секреты Windows 95" в NT'XP используется подобный механизм. Фактически, твоя прога должна взять на себя функции загрузчика и в ручную загрузить прогу в память. Но в случае NT твоя прога должна быть драйвером.

PS: Второй способ никогда не пробовал.

Kolinus » 29 сен 2004, 18:03

От создателей Windows на русском ;)
Посмотри AiK - это глава из Рихтера про потоки где все подробно объяснено - мот чем-т поможет
http://softs.h10.ru/literature.shtml?to ... =head6.htm

Kolinus » 29 сен 2004, 18:00

В Рихтере написано, что ВСЕ созданные потоком объекты разрушаются при его сметри (система ПОЛЬНОСТЬЮ чисти весь его стек)

Вернуться к началу