Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Неизвлекаемое сообщение PeekMessage 
:(
    Опции темы
Alexeis
Дата 28.11.2014, 13:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 7
Всего: 459



Имеется код проверки сообщения в очереди
Код

DWORD res = MsgWaitForMultipleObjectsEx(WaitObjHandleList.size(), &WaitObjHandleList[0], chkTimeout,
                                                   QS_ALLINPUT, MWMO_ALERTABLE | MWMO_INPUTAVAILABLE);

...
if (res == WAIT_OBJECT_0 + WaitObjHandleList.size()) //сообщение пришло
            {
                ProcessMessage();
            }



И собственно код обработки сообщений

Код

    MSG msg;
    BOOL bRet = 0;
    do
    {
        bRet = PeekMessage( &msg, NULL, 0, 0, PM_REMOVE );
        if (bRet == -1)
        {
            bRet = bRet;
            //handle the error and possibly exit
        }
        if (bRet > 0)
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
        {

        }
    }
    while (bRet != 0);


Т.е. функция PeekMessage должна вызываться ТОЛЬКО если пришло сообщение в очередь потока. Однако после тыкания мышкой по диалогу приходят какие-то странные сообщения, которые не извлекает PeekMessage
Наличие их в очереди я проверяю при помощи

Код

DWORD res = GetQueueStatus(QS_ALLINPUT);


получаю код 0x00060000 что ровняется 0x00040000 | 0x00020000
Т.е. сообщения MouseDown и МоuseMove . Все бы ничего, да после появления таких сообщений цикл обработки сообщения зацикливается и сжирает 100% времени ядра. Т.е. по сути MsgWaitForMultipleObjectsEx  видит сообщение, а PeekMessage нет, при этом GetQueueStatus также его видит.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
feodorv
Дата 28.11.2014, 15:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 9
Всего: 45



Любопытно. А Ваша очередь сообщений не была ли присоединена к другому потоку?


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
Alexeis
Дата 28.11.2014, 15:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 7
Всего: 459



Цитата(feodorv @  28.11.2014,  16:38 Найти цитируемый пост)
Любопытно. А Ваша очередь сообщений не была ли присоединена к другому потоку?

  Ситуация довольно хитрая. Это действительно обработчик сообщений дополнительного потока. В нем осуществляется работа с некоторым устройством. В нем же создается диалог ( WinAPI CreateDialog ) . Диалог имеет в качестве родителя Окно, которое создано в главном потоке. Соответственно через родителя сообщения не транслируются этому диалогу, а идут напрямую через очередь сообщений своего потока.
  Пока что ошибку провоцирую таким образом, что завешиваю на время главный поток и начинаю кликать мышкой по диалогу созданному в этом дополнительном потоке. После чего в очереди сообщений дополнительного потока появляются странные неизвлекаемые сообщения.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
feodorv
Дата 28.11.2014, 15:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 9
Всего: 45



Ага. 
Цитата
Функции GetMessage и PeekMessage проверяют флаги пробуждения только для вызывающего потока. Это значит, что потоки никогда не смогут извлечь сооб щения из очереди, присоединенной к другому потоку, включая сообщения для потоков того же процесса. 

Оконные сообщения. Как с этим быть, не знаю...


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
Alexeis
Дата 28.11.2014, 16:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 7
Всего: 459



  Да, я пока искал ошибку наткнулся на эту ссылку. У меня именно так и происходит. В дополнительном потоке работает очередь обработки сообщений, эвентов, таймеров и асинхронных функций. Именно в ней и вызывается PeekMessage. При этом судя по коду возврата функции MsgWaitForMultipleObjectsEx (функция возвращает 2, при том что в списке 1 эвент и 1 Waitable Timer) это значит, что пришло сообщение. При этом есть также сработавший таймер, но вероятно функция MsgWaitForMultipleObjectsEx отдает приоритет сообщениям, а сигнал от таймера я вообще не вижу. Это как раз и указывает на то, что сообщение попав единажды в очередь не вычитывается никогда . Асинхронные вызовы я сразу отмел, так там код возврата из MsgWaitForMultipleObjectsEx другой.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Alexeis
Дата 11.2.2015, 13:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 7
Всего: 459



  Если вдруг кому интересно, эта тема получила продолжение. Ошибку с неизвлекаемым сообщением я не устранил, устранил лишь возможность ее появления. В некотором роде прояснилась природа этих сообщений. Ситуация простая
1) Есть потока А, в нем создано окно верхнего уровня.
2) Есть поток Б, в нем создано дочернее окно, родителем которого является окно из пункта 1.
3) Пытаемся взаимодействовать из потока А с окном созданном в потоке В. 

В результате в поток В посылаются псевдосообщения. Эти сообщения действительно не вычитываются при помощи PeekMessage. Функция возвращает результат - отсутствие сообщения. Назначение этих сообщений просто пробудить поток. Никакой смысловой нагрузки они не несут. Если взаимодействие с окном происходит из своего потока, то лишних сообщений нет. В обычном состоянии приходит по одному такому сообщению на одну межпотоковую операцию. Это стандартное документированное поведение.
 На счет неизвлекаемых сообщений, скорее всего там дело не в том, что сообщения неизвлекаемые, а скорее всего имеет место зацикливание при взаимодействии 2х потоков.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Dem_max
Дата 16.2.2015, 08:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 16
Всего: 39



Зачем создавать кучу потоков и в них создавать окна ?


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
Alexeis
Дата 17.2.2015, 10:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 7
Всего: 459



Цитата(Dem_max @  16.2.2015,  09:06 Найти цитируемый пост)
Зачем создавать кучу потоков и в них создавать окна ?

  Чтобы избежать лишней синхронизации. Когда оконные операции производятся в главном потоке, то приходится ждать главный поток. С оконным интерфейсом иногда возникают всякие непредвиденные выкрутасы типа
  Модель -> Вид -> контроллер -> Модель. Уведомлять нужно синхронно. Если все запущенно в 2х потоках, то нередко ловлю дедлоки. В одном потоке все проще.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
GremlinProg
Дата 22.2.2015, 18:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Ну в общем случае - окна не для мультитрединга. Если надо разделить работу по потокам в окнах, то это уже плохая идея. Понимайте, что окна - это декоративный слой пирога (самый верхний). Работой должны заниматься простые потоки, с простой синхронизацией. Окна - лишь представление их результатов и/или исходных данных.


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Alexeis
Дата 23.2.2015, 02:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 7
Всего: 459



Цитата(GremlinProg @  22.2.2015,  19:06 Найти цитируемый пост)
Если надо разделить работу по потокам в окнах, то это уже плохая идея. Понимайте, что окна - это декоративный слой пирога (самый верхний).

  На самом деле лучшим решением было вообще разделить по разным процессам. Но межпроцессное взаимодействие недешево и не быстро. Не исключено, что я к этому еще приду. 

Цитата(GremlinProg @  22.2.2015,  19:06 Найти цитируемый пост)
Понимайте, что окна - это декоративный слой пирога (самый верхний). Работой должны заниматься простые потоки, с простой синхронизацией. Окна - лишь представление их результатов и/или исходных данных. 

  Окна это не только представление. Если бы все так было просто, то не требовалось бы никакой синхронизации. В первом приближении так задача и была решена. Заводится таймер в потоке GDI он проверяет изменилось ли состояние и если изменилось, то обновляет. 
  Но проблема в том, что окна управляют процессами. На оснований действий пользователя запускаются команды. В любом случае должна работать последовательность.
  Интерфейс -> действие -> команда -> изменение модели -> окончание команды -> подтверждение действия -> уведомление пользователя. 
  Недопустимо чтобы действие пользователя ни к чему не привело, или не было никакой реакции на его действие. Если интерфейс реализовать в отдельном потоке, то код контроллера приходится реализовывать в том же потоке что и модель, а это уже означает целый геморрой. Нужно в этом потоке создавать очередь для команд, каждую команду создавать в виде отдельного объекта в куче, предусматривать механизмы для слежения за очередью, и т.д. и т.п. а в конце оказывается, что некоторые команды важнее других и если модели сказали стоп, беги, назад, лети, то не нужно выполнять стоп, беги, назад, а нужно сразу лететь, а может иногда нужно стоп, а иногда лети. 
  
  Синхронное исполнение, когда модель, контроллер и вид в одном потоке в 1000 раз упрощают всю работу.
Пользователь всегда может начать действие, проследить за исполнением текущего действия, или отменить текущую операцию. И синхронность никак не позволит ему начать несколько операций.

  Если же контроллер и вид реализуются в одном и том же потоке, то контроллер начнет блокировать и поток вида и поток модели (для обеспечения синхронности). Это обширное поле для всяких дедлоков и фризов. 

Это сообщение отредактировал(а) Alexeis - 23.2.2015, 02:32


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
GremlinProg
Дата 23.2.2015, 19:15 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(Alexeis @  23.2.2015,  04:26 Найти цитируемый пост)
Если бы все так было просто, то не требовалось бы никакой синхронизации.

Обычно так и происходит, т.е. - просто. Если уже получается "не просто", значит вы решаете чужую задачу. Подумайте, может стоит выделить какой-то простой протокол управления вашим ядром и уже к нему прикрутить GUI. Тогда GUI можно делать интерактивным или нет. Первую версию можно было бы сделать вообще синхронной. Думаю, надо стремиться к такой модульности программ, как раз, чтобы они были простыми.
Цитата(Alexeis @  23.2.2015,  04:26 Найти цитируемый пост)
Но проблема в том, что окна управляют процессами.

Окна - прослойка между пользователем и системой - интерфейс взаимодействия. Конечно, они могут быть сложными, но они не должны решать чужие задачи. Определить ошибку оч. просто: если работа GUI влияет на результаты работы программы, значит что-то уже сделано не так - отделяйте мух от котлет.


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.1304 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.