Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Системное программирование и WinAPI > Пара вопросов по оконным сообщениям |
Автор: GIK 7.1.2009, 14:35 |
Всем доброго времени суток. Читаю книгу Джефри Рихтера по WIN32, изучаю Visual C++. Дошел до Оконных Сообщений. Мне практически понятен принцип... но есть пара глупых вопросов... В чем отличие Синхронных от Асинхронных сообщений? ![]() |
Автор: GremlinProg 7.1.2009, 14:57 |
синхронные сообщения передаются в оконную процедуру напрямую, т.е. в том же потоке, где и вызывается SendMessage, а результат обработки сообщения возвращается непосредственно из SendMessage асинхронные ставятся в конец очереди сообщений с помощью функций PostMessage, SendNotifyMessage и SendMessageCallback результат их обработки ни как не передается обратно, поскольку реальная обработка такого сообщения, в общем случае, не связана с текущим потоком, в котором это сообщение было отправлено, поэтому и передача любых локальных указателей (на стековые переменные) с асинхронным сообщением повлечет за собой ошибки доступа по несуществующим адресам памяти синхронные используются когда необходимо немедленно получить результат асинхронные удобно использовать, когда нужно уведомлять окно о каких-либо произошедших событиях, не дожидаясь на них реакции окна, например: из параллельных потоков |
Автор: Earnest 7.1.2009, 15:25 |
Немного уточню. Все в разъяснении GremlinProg будет правильно, если под "потоком" подразумевается поток управления, а не поток в в смысле "thread". Сообщение, синхронное или асинхронное - всегда обрабатывается в том потоке (thread), которому принадлежит окно. Если сообщение послано синхронно окну другого потока, то посылающий поток приостанавливается до обработки сообщения. Таким образом возникает иллюзия обычного вызова функции. Но это нужно понимать очень хорошо, т.к. здесь возможно возникновение dead-lock'ов. Поэтому разумно посылать сообщения синхронно, только если это действительно нужно. А при посылке сообщения окну другого потока анализировать возможность взаимоблокировок. |
Автор: GremlinProg 7.1.2009, 15:55 |
Earnest, ну ты так его совсем запутаешь, теперь он будет сомневаться, что такое поток поток он и в африке бы был потоком, если бы не STL со своим нововведением stream, все остальное как ни назови, нить, поток - условно разделенные во времени "процессы", исполнение которых может накладываться друг на друга в одних и тех же временных интервалах окно - не поток, и нету у него специального потока управления, оно может только принадлежать потоку, т.е. управление его поведением производится только во время работы этого потока-владельца если создать в двух разных потоках два окна, то они уже не будут работать на одной временной шкале, т.е. в любом случае, синхронная передача сообщений между ними потребует синхронизации между этими потоками, что и делает SendMessage PostMessage - синхронизирует только доступ к очереди сообщений, чтобы вставить новое сообщение, поэтому, она более лояльна к асинхронным операциям а что касается лексической разницы асинхронного и синхронного сообщения, то она аналогична разнице между процедурой и функцией: функция - возвращает результат работы, а процедура - не возвращает |
Автор: GremlinProg 7.1.2009, 18:11 | ||||||
ну, про потоки ввода вывода я и не пишу речь идет как раз об общем случае, в котором нет уточнений о том, какие существуют особенности асинхронных пересылок: в одном потоке, или в разных; один поток - это частный случай, который и выделяется соответственно в документации, например так:
поэтому и не разделяю такое мнение:
хорошо, что расшифровала "потоки управления", хотя потоком, в контексте асинхронных пересылок, я бы это не называл, поскольку очевидна путаница в терминах, это цепочка, или итерация, как удобно, но не поток, мы же не называем тело цикла потоком, а здесь, думаю, эта асоциация более верная думаю только зря я обобщил Post и Send, поскольку разница между ними как раз в очередности обработки: Post - ставит сообщение в конец очереди Send - в начало (хотя "в начало" - это лишь условность, поскольку это равнозначно передаче сообщения непосредственно в процедуру окна, обычно так и пишут "calls the window procedure") Добавлено через 8 минут и 6 секунд
поэтому в си и нет процедур ) |
Автор: Earnest 8.1.2009, 09:03 | ||
Ну это не то чтобы путаница в терминах, а скорее историческое использование слова "поток" для перевода различных сущностей: stream - поток ввода\вывода, workflow - поток управления, thread - поток выполнения. Я понимаю, что по-русски мутновато получается, зато по английски все предельно ясно. Недаром одно время были активные сторонники переводить thread как "нить", чтобы не путать с workflow. Но как-то не прижилось. Раз уж пошла битва цитат, то вот что говорит MSDN о SendMessage:
Так что SendMessage ни в какую очередь ничего не помещает, а вызывает оконную процедура напрямую или делает вид, что вызывает напрямую. |
Автор: GIK 8.1.2009, 15:22 |
![]() Народ, Бальшой Прибальшой Спасиб что разьяснили... щас буду обмозговывать ![]() |
Автор: GIK 8.1.2009, 17:07 | ||
чет я ваще запутался товарищи ![]() ![]() Давайте со мной как с ребенком, я щас буду свою мысль выкладывать а Вы плиз, по возможности поправте меня... 1) Как я понял Синхронное сообщение отличается от Асинхронных тем, что Синхронное обрабатывается сразу или почти сразу, т.е. в первую очередь. Я прав, только в этом отличие? ![]() 2) [quote(Рихтер)] Вот как работает SendMessage. Если поток вызывает SendMessage для посылки сообщения окну, созданному им же, то функция просто обращается к оконной процедуре соответствующего окна как к подпрограмме. [/quote] [quote(GremlinProg )] синхронные сообщения передаются в оконную процедуру напрямую, т.е. в том же потоке, где и вызывается SendMessage, а результат обработки сообщения возвращается непосредственно из SendMessage [/quote] Т.е. неставиться в очередь структуры THREADINFO, а обрабатывается сразу в оконную процедуру, или между оконной процедурой и посылом сообщения есть еще что то по мимо структуры THREADINFO в которой и содержатся все сообщения? И еще, вот это:
и есть оконная процедура? или это что то недокументированное? Объясните пока только это, а про посыл другим окном (не из вызывающего процесса) пока ненадо, а то у меня в голове такая каша теперь ![]() |
Автор: GremlinProg 8.1.2009, 18:20 | ||||||||
не спорю, читай внимательно, что я по этому поводу написал, условность я ввел только для обобщения работы для методов post и send, чтобы разница была наглядной, чтобы общее между ними была очередь сообщений GIK, я попробую привести упрощенный аналог главный цикл обработки сообщений:
так можно показать главный цикл сообщений (Main message loop), т.е. на каждой итерации извлекается последнее сообщение из очереди и передается на обработку в процедуру окна теперь, допустим где-нибудь мы вызываем метод SendMessage(так-же, упрощенно):
а теперь то же самое, только асинхронно:
ну вот и разница оконная процедура - это WindowProc, Main message loop - это главный цикл обработки сообщений, в нем как раз и осуществляется работа с очередью и обработкой сообщений тут я явно показал зависимости для наглядности, можно, конечно точнее, но тогда получится многобуков, будет непонятно |
Автор: GIK 9.1.2009, 17:07 | ||
GremlinProg, спасиб тебе огромный за разьяснения, я все понял, или думаю что все понял ![]() Отетьте теперь на такой вопрос: Передавая синхронное сообщение другому потоку, это сообщение, (если поток не занят)ожидается функцией GetMessage, и уже после нее СТАВИТЬСЯ В ОЧЕРЕДЬ синхронных сообщений, а НЕ отсылается сразу на обработку в WindowProc(), как это делается при отправки сообщений в ЭТОМ же потоке. Это так или нет? ![]() И еще, все таки, через:
проходят какие сообщения? ![]() |
Автор: Earnest 9.1.2009, 19:18 |
Нет, то что посылается через SendMessage, никогда в очередь не попадает. И в цикл GetMessage, соответственно, тоже. Просто вызывающий поток приостанавливается, а внутри SendMessage происходит переключение на поток окна и передача ему управления. |