![]() |
Модераторы: feodorv, GremlinProg, xvr, Fixin |
![]() ![]() ![]() |
|
Alexeis |
|
||||||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 7 Всего: 459 |
Имеется код проверки сообщения в очереди
И собственно код обработки сообщений
Т.е. функция PeekMessage должна вызываться ТОЛЬКО если пришло сообщение в очередь потока. Однако после тыкания мышкой по диалогу приходят какие-то странные сообщения, которые не извлекает PeekMessage Наличие их в очереди я проверяю при помощи
получаю код 0x00060000 что ровняется 0x00040000 | 0x00020000 Т.е. сообщения MouseDown и МоuseMove . Все бы ничего, да после появления таких сообщений цикл обработки сообщения зацикливается и сжирает 100% времени ядра. Т.е. по сути MsgWaitForMultipleObjectsEx видит сообщение, а PeekMessage нет, при этом GetQueueStatus также его видит. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
||||||
|
|||||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 9 Всего: 45 |
Любопытно. А Ваша очередь сообщений не была ли присоединена к другому потоку?
-------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 7 Всего: 459 |
Ситуация довольно хитрая. Это действительно обработчик сообщений дополнительного потока. В нем осуществляется работа с некоторым устройством. В нем же создается диалог ( WinAPI CreateDialog ) . Диалог имеет в качестве родителя Окно, которое создано в главном потоке. Соответственно через родителя сообщения не транслируются этому диалогу, а идут напрямую через очередь сообщений своего потока. Пока что ошибку провоцирую таким образом, что завешиваю на время главный поток и начинаю кликать мышкой по диалогу созданному в этом дополнительном потоке. После чего в очереди сообщений дополнительного потока появляются странные неизвлекаемые сообщения. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 9 Всего: 45 |
Ага.
Оконные сообщения. Как с этим быть, не знаю... -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 7 Всего: 459 |
Да, я пока искал ошибку наткнулся на эту ссылку. У меня именно так и происходит. В дополнительном потоке работает очередь обработки сообщений, эвентов, таймеров и асинхронных функций. Именно в ней и вызывается PeekMessage. При этом судя по коду возврата функции MsgWaitForMultipleObjectsEx (функция возвращает 2, при том что в списке 1 эвент и 1 Waitable Timer) это значит, что пришло сообщение. При этом есть также сработавший таймер, но вероятно функция MsgWaitForMultipleObjectsEx отдает приоритет сообщениям, а сигнал от таймера я вообще не вижу. Это как раз и указывает на то, что сообщение попав единажды в очередь не вычитывается никогда . Асинхронные вызовы я сразу отмел, так там код возврата из MsgWaitForMultipleObjectsEx другой.
-------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 7 Всего: 459 |
Если вдруг кому интересно, эта тема получила продолжение. Ошибку с неизвлекаемым сообщением я не устранил, устранил лишь возможность ее появления. В некотором роде прояснилась природа этих сообщений. Ситуация простая
1) Есть потока А, в нем создано окно верхнего уровня. 2) Есть поток Б, в нем создано дочернее окно, родителем которого является окно из пункта 1. 3) Пытаемся взаимодействовать из потока А с окном созданном в потоке В. В результате в поток В посылаются псевдосообщения. Эти сообщения действительно не вычитываются при помощи PeekMessage. Функция возвращает результат - отсутствие сообщения. Назначение этих сообщений просто пробудить поток. Никакой смысловой нагрузки они не несут. Если взаимодействие с окном происходит из своего потока, то лишних сообщений нет. В обычном состоянии приходит по одному такому сообщению на одну межпотоковую операцию. Это стандартное документированное поведение. На счет неизвлекаемых сообщений, скорее всего там дело не в том, что сообщения неизвлекаемые, а скорее всего имеет место зацикливание при взаимодействии 2х потоков. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
Dem_max |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1780 Регистрация: 12.4.2007 Репутация: 16 Всего: 39 |
Зачем создавать кучу потоков и в них создавать окна ?
-------------------- Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte") |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 7 Всего: 459 |
Чтобы избежать лишней синхронизации. Когда оконные операции производятся в главном потоке, то приходится ждать главный поток. С оконным интерфейсом иногда возникают всякие непредвиденные выкрутасы типа Модель -> Вид -> контроллер -> Модель. Уведомлять нужно синхронно. Если все запущенно в 2х потоках, то нередко ловлю дедлоки. В одном потоке все проще. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
GremlinProg |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
Ну в общем случае - окна не для мультитрединга. Если надо разделить работу по потокам в окнах, то это уже плохая идея. Понимайте, что окна - это декоративный слой пирога (самый верхний). Работой должны заниматься простые потоки, с простой синхронизацией. Окна - лишь представление их результатов и/или исходных данных.
-------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 7 Всего: 459 |
На самом деле лучшим решением было вообще разделить по разным процессам. Но межпроцессное взаимодействие недешево и не быстро. Не исключено, что я к этому еще приду. Окна это не только представление. Если бы все так было просто, то не требовалось бы никакой синхронизации. В первом приближении так задача и была решена. Заводится таймер в потоке GDI он проверяет изменилось ли состояние и если изменилось, то обновляет. Но проблема в том, что окна управляют процессами. На оснований действий пользователя запускаются команды. В любом случае должна работать последовательность. Интерфейс -> действие -> команда -> изменение модели -> окончание команды -> подтверждение действия -> уведомление пользователя. Недопустимо чтобы действие пользователя ни к чему не привело, или не было никакой реакции на его действие. Если интерфейс реализовать в отдельном потоке, то код контроллера приходится реализовывать в том же потоке что и модель, а это уже означает целый геморрой. Нужно в этом потоке создавать очередь для команд, каждую команду создавать в виде отдельного объекта в куче, предусматривать механизмы для слежения за очередью, и т.д. и т.п. а в конце оказывается, что некоторые команды важнее других и если модели сказали стоп, беги, назад, лети, то не нужно выполнять стоп, беги, назад, а нужно сразу лететь, а может иногда нужно стоп, а иногда лети. Синхронное исполнение, когда модель, контроллер и вид в одном потоке в 1000 раз упрощают всю работу. Пользователь всегда может начать действие, проследить за исполнением текущего действия, или отменить текущую операцию. И синхронность никак не позволит ему начать несколько операций. Если же контроллер и вид реализуются в одном и том же потоке, то контроллер начнет блокировать и поток вида и поток модели (для обеспечения синхронности). Это обширное поле для всяких дедлоков и фризов. Это сообщение отредактировал(а) Alexeis - 23.2.2015, 02:32 -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
GremlinProg |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
Обычно так и происходит, т.е. - просто. Если уже получается "не просто", значит вы решаете чужую задачу. Подумайте, может стоит выделить какой-то простой протокол управления вашим ядром и уже к нему прикрутить GUI. Тогда GUI можно делать интерактивным или нет. Первую версию можно было бы сделать вообще синхронной. Думаю, надо стремиться к такой модульности программ, как раз, чтобы они были простыми. Окна - прослойка между пользователем и системой - интерфейс взаимодействия. Конечно, они могут быть сложными, но они не должны решать чужие задачи. Определить ошибку оч. просто: если работа GUI влияет на результаты работы программы, значит что-то уже сделано не так - отделяйте мух от котлет. -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
![]() ![]() ![]() |
Правила форума "C/C++: Системное программирование и WinAPI" | |
|
На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы . Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |