![]() |
|
![]() ![]() ![]() |
|
Dreamer_0x01 |
|
|||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
У меня есть поток, производный от CWinThread.
Мне нужно сделать что-то аналогичное PostThreadMessage(), но только чтобы такой вызов работал по типу функции SendMessage, то есть до обработки сообщения переход к следующей за вызовом этой функции команде не осуществлялся. -------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
|||
|
||||
Fin |
|
|||
![]() Дракон->Спать(); ![]() ![]() Профиль Группа: Участник Сообщений: 687 Регистрация: 4.1.2006 Репутация: 1 Всего: 10 |
Можно объединить очереди потоков, и работать уже как обычно в одной очереди. Описано в книге Рихтера.
-------------------- Пролетал мимо. |
|||
|
||||
Dreamer_0x01 |
|
|||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
у меня нет книги Рихтера. Можно пример?
-------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
|||
|
||||
Fin |
|
||||
![]() Дракон->Спать(); ![]() ![]() Профиль Группа: Участник Сообщений: 687 Регистрация: 4.1.2006 Репутация: 1 Всего: 10 |
Вот цитата из Рихтера по твоему вопросу.
Рихтер не рекомендует связывать очереди. Так как провис одного потока, может отразится на работе второго. -------------------- Пролетал мимо. |
||||
|
|||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 87 Всего: 183 |
Функция SendMessageCallback работает не так, как нужно Dreamer'у: она возвращает управление сразу же, а не ждет, пока сообщение обработают.
А вот функция SendMessage как раз ждет. Dreamer_0x01, ты ведь знаешь, что даже PostThreadMessage ты можешь вызвать только для потока у которого есть очередь сообщений (т.е. интерфейсного)? А значит и окно есть. Ну и отправляй синхронные сообщения главному окну этого потока. Нарисуй метод MyThread::SendThreadMessage, чтобы инкапсулировать это. И поаккуратнее с SendMessage - можешь легко получить Deadlock. Если же поток не интерфейсный, то никаких сообщений, только события и прочие объекты синхронизации. -------------------- ... |
|||
|
||||
Dreamer_0x01 |
|
|||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
Ага, интерфейсный, я специально ради такого механизма и замутил это дело, хочу попробовать,мне кажется, будет удобно весьма. А где его взять, главное окно-то? И как потом это главное окно завтавить пересылать сообщения этому потоку? ручную? Или есть какой-то механизм, позволяющий "высасывать" сообщения из главного окна? -------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
|||
|
||||
Earnest |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 87 Всего: 183 |
Что значит, где взять? Пусть будет первое попавшеся окно потока. Ну или создай, в конце концов - тогда уж только для приема сообщения потока.
Ага, называется "цикл обработки сообщений" (GetMessage - DispatchMessage). ![]()
Так, стоп. Что значит "пересылать"? Сообщения, посланные окну, всегда обрабтываются в потоке этого окна. -------------------- ... |
||||
|
|||||
Dreamer_0x01 |
|
||||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
Я уже ничего не понимаю и запутался. Поток я создаю так:
B где мне взять здесь это самое окно? А куда мне вставить эту конструкцию? Надо переопределить метод Run(), или какой-то другой метод? -------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
||||
|
|||||
Fin |
|
||||
![]() Дракон->Спать(); ![]() ![]() Профиль Группа: Участник Сообщений: 687 Регистрация: 4.1.2006 Репутация: 1 Всего: 10 |
PS Прошу прошение за орфографию. Такова оцифровка электронного варианта.
Для прояснения ситуации, вот еше несколько цитат:
Из этой цитаты следует, что любой поток может иметь очередь сообшений. И эта очередь создается автоматически. Без лишних усилий со стороны программиста.
Это сообщение отредактировал(а) Fin - 20.1.2006, 16:36 -------------------- Пролетал мимо. |
||||
|
|||||
Dreamer_0x01 |
|
|||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
Fin
Вс это конечно хорошо, но у меня на данном этапе нет окон, а SendMessage требует дескриптер окна, где же его взять? -------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
|||
|
||||
Fin |
|
|||
![]() Дракон->Спать(); ![]() ![]() Профиль Группа: Участник Сообщений: 687 Регистрация: 4.1.2006 Репутация: 1 Всего: 10 |
Для чего тебе нужно посылать сообшение потоку с подтверждением о исполнении?
Если изменять параметры работы потока, то это можно сделать другими путями. Например тот же объект ядра Event. Опускаеш флаг, поток останавливаается. Ты своей функцией меняеш напрямую его параметры, затем обратно запускаеш поток. Все потоки в одном процессе находятся в одном адресном пространстве. Поэтому проблем с записью в память чужого потока, я лично не вижу. -------------------- Пролетал мимо. |
|||
|
||||
Dreamer_0x01 |
|
||||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
Для синхронизации.
В предыдущей версии было так и сделано, у меня был рабочий поток, в которую передавался указатель на структуру, содержащую в себе критическую секцию, я по ней и синхронизировался. А главному окну уже слал SendMessage, в котором отчитывался о проделанных действиях. Но получилось так, что большую часть времени у меня поток простаивает, а когда пользователь совершает какие-то действия в главном окне,поток должен был выполнить массу действий и ответить. Поэтому рабочий поток содержал в себе цикл, в котором все время опршивалось состояни нескольких переменных и в зависимости от них выполнялись какие-то действия. Состояния этих переменных, как и положено, обновлялись с заходом в критическую секцию. Я подумал, что вся эта фигня стала похожа на обыкновенный цикл обработки сообщений. Вот я и подумал, а не попробовать ли действительно воспользоваться для этой цели интерфейсным потоком и уже готовым циклом обработки сообщений. -------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
||||
|
|||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 87 Всего: 183 |
Из MSDN:
Functions to Override When Creating a User-Interface Thread ExitInstance Perform cleanup when thread terminates. Usually overridden. InitInstance Perform thread instance initialization. Must be overridden. OnIdle Perform thread-specific idle-time processing. Not usually overridden. PreTranslateMessage Filter messages before they are dispatched to TranslateMessage and DispatchMessage. Not usually overridden. ProcessWndProcException Intercept unhandled exceptions thrown by the thread's message and command handlers. Not usually overridden. Run Controlling function for the thread. Contains the message pump. Rarely overridden. Т.е. можно переопределить и Run, но лучше PreTranslateMessage. НО: как я понимаю, никаких окон в этом потоке ты создавать не предполагал. Если все же соберешься создать - то в InitInstance. Однако, как-то это криво - создать никому не нужное окно, только чтобы добиться синхронной передачи сообщений. Я бы попробовала обеспечить синхронизацию сама: пишем функцию SendThreadMessage, в которой вызываем PostThreadMessage, и потом ждем специально созданного события. Естественно, еще потребуется какой-нибудь флаг, чтобы MyThread при обработке сообщения знал, что нужно сигналить событие. SetEvent я бы поставила в переопределенной PumpMessage (посмотри родной код Run). -------------------- ... |
|||
|
||||
Dreamer_0x01 |
|
||||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
Слава богу, меня хоть кто-то понял =)
Я вот тоже думал о подобном, но решил, что изобретаю велосипед. Ладно,допустим, ишу такую функцию сам. Что мне надо сделать в PreTranslateMessage? Нужно проверять некий флаг, который будет выставлять моя функция SendThreadMessage(), и его сбрасывать, в случае, если он установлен, это ясно. Перед сбрасыванием мне нужно установить какое-то событие, это я тоже понял. А в самой функции SendThreadMessage() мне нужно после вызова PostThreadMessage ждать этого самого события. Но вот что такое события MFC и с чем их едят, я не знаю. Можно пример использования? Только просьба в МСДН не отсылать, там все по-английски, а от этого языка меня на рвоту тянет. ;) -------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
||||
|
|||||
Fin |
|
|||
![]() Дракон->Спать(); ![]() ![]() Профиль Группа: Участник Сообщений: 687 Регистрация: 4.1.2006 Репутация: 1 Всего: 10 |
Кто мешает в потоке сделать примерно такой код.
Это сообщение отредактировал(а) Fin - 20.1.2006, 17:48 -------------------- Пролетал мимо. |
|||
|
||||
![]() ![]() ![]() |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |