Как работает SendMessage для разных нитей/процессов? В какой момент происходит вызов функции окна: когда опустошится очередь сообщений, когда нить заснет(станет свободной) или еще как-то?
V>Как работает SendMessage для разных нитей/процессов? В какой момент происходит вызов функции окна: когда опустошится очередь сообщений, когда нить заснет(станет свободной) или еще как-то?
Вопрос не совсем понятен, что конкретно нужно? Или просто интересно? :o)
Попробую ответить :-/
1. Поток, пославший SendMessage, тормозится системой пока сообщение не будет обработано (в отличии от PostMesssage).
2. Вызов функции окна происходит в любой момент, если в очереди сообщений есть хотя бы одно сообщение.
3. Очередь опустошится, когда вызов обработчика сообщений вызовется столько раз сколько сообщений в очереди :o) Вызовы не производятся параллельно.
4. ?
Если на пальцах, то представь, что ты занимаешся обработкой входящей почты компании "Get Any Message". Твоя основная работа — ждать прихода почтальона и бегать доставлять сообщения нуждающимся. Большую часть своего трудового дня ты крепко спишь. Когда приходит почтальон, то тебя бесцеремонно будят и вручают ОДНО письмо, только одно. Дальше ты бежишь с ним к получателю (кстати, вместе с тобой крепко спала вся контора... вот бы найти такую работку... хочу быть приложением виндоуз :), пинаешь его, вручаешь ему письмо и стоишь ждёшь, пока он его почитает, почешет репу и может быть сделает ещё что-нибудь полезное, например некотырые отморозки любят рисовать всякую фигню прямо на окне. Пока ты с деловым видом бегаешь по конторе, к тебе могут прийти другие почтальоны. Почтальоны бывают разные, некоторые спокойно занимают очередь и смирно стоят ждут, есть хамы, которые наровят пролесть без очереди, обосновывая это своим высоким приоритетом (из них может образоваться своя очередь в начале общей очереди, всё как обычно :), есть такие, которые посмотрев, кто тут уже стоит и увидев знакомого с аналогичным сообщением могут развернуться и свалить (так поступают нигодяи, которых посылает дядя Таймер). Наконец ты разобрался с первым письмом и, валясь с ног, еле-еле добираешся до своего места, говоришь первому почтальону, что информация доставлена и пытаешься немного расслабится, но здесь тебя опять дёргают и заставляют обработать следующее сообщение... и так, пока ты не удовлетворишь всех почтальонов или... пользователь не вырубит компьютер. Что касается SendMessage, то для имитации бурной деятельности твоей конторе нужно тоже иногда рассылать сообщения. Она это может делать двумя способами, через SendMessage или PostMessage. Первый случай подразумевает обязательное ожидание доставки, обработки сообщения и получения уведомления. Этот способ очень удобен, так как пока почтальон бегает с твоим письмом ты и вся твоя контора можете спать со спокойной совестью, у тебя есть отмазка — ты должен получить уведомление о доставке. Второй способ в этом смысле не так удобен, тебе придётся продолжить работу сразу после того как почтальон унесёт твоё сообщение, поэтому этот способ применяется гораздо реже.
Happy coding,
Igor.
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: как работает SendMessage
От:
Аноним
Дата:
25.06.01 07:50
Оценка:
IT>Вопрос не совсем понятен, что конкретно нужно? Или просто интересно? :o)
Меня интересует синхронизация. Допустим во время вызовова вызываемый поток занят (находится в обработчике сообщения). Когда произойдет вызов функции окна (в каком месте цикла обработки сообщений)? Может сообщение поместится в очередь и вызывающему потоку вернется ответ когда будет произведен вызов GetMessage/DispatchMessage c соответсвущим сообщением?
Я просто хочу приспособить SendMessage в том числе и для целей синхронизации потоков одного процесса. И меня интересует, не повлечет ли это каких либо побочных эффектов.
Re[3]: как работает SendMessage
От:
Аноним
Дата:
25.06.01 09:26
Оценка:
Здравствуйте Аноним, вы писали:
IT>>Вопрос не совсем понятен, что конкретно нужно? Или просто интересно? :o)
А>Меня интересует синхронизация. Допустим во время вызовова вызываемый поток занят (находится в обработчике сообщения). Когда произойдет вызов функции окна (в каком месте цикла обработки сообщений)? Может сообщение поместится в очередь и вызывающему потоку вернется ответ когда будет произведен вызов GetMessage/DispatchMessage c соответсвущим сообщением?
А>Я просто хочу приспособить SendMessage в том числе и для целей синхронизации потоков одного процесса. И меня интересует, не повлечет ли это каких либо побочных эффектов.
Что бы поток пославщий сообщение не ждал его обработки а мог спокойно продолжить свою работу нужно послать ему сообшение(вызвать функцию, не иначе, ни в коем случае не надо делать SendMessage(..) ;-))) — делаеш ReplayMessage(LRESULT res ) и вызывающий поток продолжает работу с чистой совестью )))
IT>>Вопрос не совсем понятен, что конкретно нужно? Или просто интересно? :o)
А>Меня интересует синхронизация. Допустим во время вызовова вызываемый поток занят (находится в обработчике сообщения). Когда произойдет вызов функции окна (в каком месте цикла обработки сообщений)? Может сообщение поместится в очередь и вызывающему потоку вернется ответ когда будет произведен вызов GetMessage/DispatchMessage c соответсвущим сообщением?
Точно так и будет.
А>Я просто хочу приспособить SendMessage в том числе и для целей синхронизации потоков одного процесса.
Вполне законное желание.
A>И меня интересует, не повлечет ли это каких либо побочных эффектов.
Обычные побочные эффекты, которые бывают при синхронизации :)
Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: как работает SendMessage
От:
Аноним
Дата:
25.06.01 12:14
Оценка:
Здравствуйте IT, вы писали:
IT>>>Вопрос не совсем понятен, что конкретно нужно? Или просто интересно? :o)
А>>Меня интересует синхронизация. Допустим во время вызовова вызываемый поток занят (находится в обработчике сообщения). Когда произойдет вызов функции окна (в каком месте цикла обработки сообщений)? Может сообщение поместится в очередь и вызывающему потоку вернется ответ когда будет произведен вызов GetMessage/DispatchMessage c соответсвущим сообщением?
IT>Точно так и будет.
Не совсем... Вызывающему потоку ответ вернётся когда вызываемый поток полностью обработает пришедшее к ниму с вызовом ::SendMessage(...) сообщение , не ранее. Либо после вызова вызываемым потоком метода ::ReplayMessage(...)
Может сообщение поместится в очередь и вызывающему потоку вернется ответ когда будет произведен вызов GetMessage/DispatchMessage c соответсвущим сообщением?
IT>>Точно так и будет.
A>Не совсем... Вызывающему потоку ответ вернётся когда вызываемый поток полностью обработает пришедшее к ниму с вызовом ::SendMessage(...) сообщение , не ранее. Либо после вызова вызываемым потоком метода ::ReplayMessage(...)
А разве выше речь не об том же? 8-/
Если нам не помогут, то мы тоже никого не пощадим.
Re[6]: как работает SendMessage
От:
Аноним
Дата:
26.06.01 06:16
Оценка:
Здравствуйте IT, вы писали:
IT>Может сообщение поместится в очередь и вызывающему потоку вернется ответ когда будет произведен вызов GetMessage/DispatchMessage c соответсвущим сообщением?
IT>>>Точно так и будет.
A>>Не совсем... Вызывающему потоку ответ вернётся когда вызываемый поток полностью обработает пришедшее к ниму с вызовом ::SendMessage(...) сообщение , не ранее. Либо после вызова вызываемым потоком метода ::ReplayMessage(...)
IT>А разве выше речь не об том же? 8-/
**** вызывающему потоку вернется ответ когда будет произведен вызов GetMessage/DispatchMessage c соответсвущим сообщением?
*********
Мне показалось, что имеется в виду как только вызвана функция DispatchMessage(...) управление возвращается хотя на самом деле может пройти ещё несколько минут или часов )))
Re[7]: как работает SendMessage
От:
Аноним
Дата:
27.06.01 08:35
Оценка:
Здравствуйте Antony, вы писали:
A>Здравствуйте IT, вы писали:
IT>>Может сообщение поместится в очередь и вызывающему потоку вернется ответ когда будет произведен вызов GetMessage/DispatchMessage c соответсвущим сообщением?
IT>>>>Точно так и будет.
A>>>Не совсем... Вызывающему потоку ответ вернётся когда вызываемый поток полностью обработает пришедшее к ниму с вызовом ::SendMessage(...) сообщение , не ранее. Либо после вызова вызываемым потоком метода ::ReplayMessage(...)
IT>>А разве выше речь не об том же? 8-/
A>**** вызывающему потоку вернется ответ когда будет произведен вызов GetMessage/DispatchMessage c соответсвущим сообщением? A>*********
A>Мне показалось, что имеется в виду как только вызвана функция DispatchMessage(...) управление возвращается хотя на самом деле может пройти ещё несколько минут или часов )))
Кстати ещё одна немаловажная деталь. Сообщения отправленные с помощью SendMessage(...), не системой а пользователем, вообще не поподают в очередь сообщений потока, а уходят напрямую в окно — параметр hWnd. Поэтому не имеет смысла ставить фильтры в главной функции потока.
Здравствуйте Antony, вы писали:
A>Кстати ещё одна немаловажная деталь. Сообщения отправленные с помощью SendMessage(...), не системой а пользователем, вообще не поподают в очередь сообщений потока, а уходят напрямую в окно — параметр hWnd. Поэтому не имеет смысла ставить фильтры в главной функции потока.
Сообщения, посланные системой через SendMessage, туда тоже не попадают.
Здравствуйте hVint, вы писали:
V>Как работает SendMessage для разных нитей/процессов? В какой момент происходит вызов функции окна: когда опустошится очередь сообщений, когда нить заснет(станет свободной) или еще как-то?
Каждый поток имеет 4 очереди сообщений:
— очередь асинхроныых сообщений. Сюда попадают сообщения, посланные PostMessage
— Сообщения ввода. Не будем вдаваться в подробности что это такое.
— очередь синхронных сообщений. Сюда попадают сообщения посланные с помощью одной из функций SendMessage.
— очередь ответных сообщений. сюда попадают сообщения, посланные с помощью ReplayMessage.
+ поток имеет "флаги пробуждения"
Оконная процедура вызовется из DispatchMessage ( в большинстве случаев ).
-----------Посылка асинхронных сообщений------------
Возврат из PostMessage (или PostThreadMessage) происходит сразу после того, как сообщение поставлено в очередь потока. Поэтому вызывающий поток остаётся в неведении обработано сообщение или нет. Вполне возможно, что поток даже не получит это сообщение ( например если поток завершится не обработав сообщение ).
-----------Посылка синхронных сообщений------------
Оконная процедура обработает сообщение и только после этого вернёт управление.
Если поток вызывает SendMessage для посылки сообщения окну, созданному им же, то функция просто обращается к оконной процедуре как к подпрограмме.
Если поток посылает сообщение окну, созданному в другом потоке, то это сообщение ставится в очередь синхронных сообщений, а сам вызывающий поток приостанавливается в ожидании ответного сообщения. Кроме того выставляется флаг QS_SENDMESSAGE (об этом ниже). Поток, которому предназначается сообщение просматривает очередь синхронных сообщений и берёт первое. Затем вызывает оконную процедуру для данного окна.
....Детали опустим :=)
-----------Пробуждение потока------------
Когда поток вызывает GetMessage или WaitMessage и никаких сообщений для него или созданных им оконо нет, система может приостановить выполнение потока. Как только потоку будет отправлено синхронное или асинхронное сообщение, система установит флаг пробуждения, указывающий что поток должен получить процессорное время и обработать сообщение.
-----------Алгоритм выборки сообщений из очереди потока------------
QS_SENDMESSAGE -> QS_POSTMESSAGE -> QS_QUIT -> QS_INPUT -> QS_PAINT -> QS_TIMER