Разница между PostQuitMessage и PostThreadMessage(WM_QUIT)

Разговоры на любые темы: вы можете обсудить здесь какой-либо сайт, найти единомышленников или просто пообщаться...
tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Разница между PostQuitMessage и PostThreadMessage(WM_QUIT)

Сообщение tyomitch » 11.02.2005 (Пт) 11:24

В чём сабж?


(Поскольку это не насущная необходимость, а праздное любопытство, то тему решил создать в Трёпе).


У меня есть предположения, но я не уверен, и поэтому выскажу их только после того, как кто-нибудь другой выскажет свои :-)
Изображение

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 11.02.2005 (Пт) 12:06

Разница (зырит в MSDN) в том, что (продолжает зырить в MSDN), наверное (лихорадочно листает MSDN), WM_QUIT стоит особняком, и поэтому его рекомендовано юзать для него отдельную функцию. В частности, для PostMessage есть явный запрет на WM_QUIT...
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 11.02.2005 (Пт) 12:26

Так в чём-таки отличие WM_QUIT от "обычных сообщений"?
Изображение

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 11.02.2005 (Пт) 12:42

Оно не получается через мейнлуп, поскольку вызывает его уничтожение, т.к. GetMessage вернёт 0, а типовой мейнлуп делается while getmessage?
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 11.02.2005 (Пт) 15:14

Тест, подтверждающий мою невысказанную гипотезу:
Код: Выделить всё
case WM_DESTROY:
   PostQuitMessage(123);
   PostQuitMessage(456);

- вернёт 456.

Код: Выделить всё
case WM_DESTROY:
   PostThreadMessage(GetCurrentThreadId(),WM_QUIT,123,0);
   PostThreadMessage(GetCurrentThreadId(),WM_QUIT,456,0);

- вернёт 123.

Ну что, ни у кого нет предположений?
Изображение

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 11.02.2005 (Пт) 16:21

Типа PQM == "А не сдохнуть ли в ближайшем будущем?", а PTM == "Сдохнуть, однозначно"? :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

RayShade
Scarmarked
Scarmarked
Аватара пользователя
 
Сообщения: 5511
Зарегистрирован: 02.12.2002 (Пн) 17:11
Откуда: Russia, Saint-Petersburg

Сообщение RayShade » 11.02.2005 (Пт) 18:24

GSerg, вот что меня радует при чтении нашего форума, так это то, что попадаются такие классно сделанные постинги :)
I don't understand. Sorry.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 13.02.2005 (Вс) 3:07

Ввиду того, что никто на всём форуме не стал участвовать в мозговом штурме, привожу свою отгадку-догадку.

WM_QUIT - это не настоящее сообщение, по крайней мере в WinNT. Оно не шлётся в очередь потока.
Вместо этого у каждого потока в блоке состояния (TEB) есть поле "код возврата", которое возвращается функцией GetExitCodeThread.
GetMessage читает это поле, и если там не STILL_ACTIVE - на лету синтезирует MSG для WM_QUIT и возвращает в вызвавший поток.
Единственное, что делает PostQuitMessage - это записывает свой аргумент в TEB. Она никуда не шлёт никакие сообщения.
Таким образом, в тесте 1 второй вызов PostQuitMessage перезаписывает код возврата в TEB, и GetMessage при синтезе MSG для WM_QUIT использует новое значение.
С другой стороны, в тесте 2 в очередь потока на самом деле шлётся два сообщения WM_QUIT. Поскольку это очередь (FIFO), то GetMessage первым обрабатывает первое посланное сообщение, и в возвращённом MSG будет стоять первое значение.

Эксперимент в Win98 показал одинаковые результаты для PostQuitMessage и PostThreadMessage(WM_QUIT). Видимо, там WM_QUIT - нормальное сообщение, которое шлётся PostQuitMessage в очередь потока.
Изображение

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 22.02.2005 (Вт) 21:51

Картина чуть-чуть проясняется...
Рэймонд Чен написал статью про WM_QUIT ( http://weblogs.asp.net/oldnewthing/arch ... 78018.aspx ). В её обсуждении я задал сабжевый вопрос, и получил следующие ответы:
Raymond Chen писал(а):I'll return to this topic in a few months.

rrrr писал(а):As far as I know PostQuitMessage sets a flag only and PostThreadMessage posts a real message.

Выводы:
- похоже, моя догадка верна;
- мы скоро узнаем наверняка.
Изображение

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 23.02.2005 (Ср) 5:11

Если твоя догадка и верна (что может быть - я не спорю :)), то она не совсем точна :)
Дело в том, что (столкнулся при написании Waiter!'а) STILL_ACTIVE тоже является допустимым кодом возврата! Соответственно, функция, проверяющая это значение, может впасть в дедлок в том случае, когда тред реально завершил работу, а вернул число, совпадающее со STILL_ACTIVE. Так что такой метод проверки не подходит :)
Подошло бы тестирование через WfSO, но тогда, получается, винда должна сама открывать HANDLE на SYNCHRONIZE, тестировать и закрывать :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 04.11.2005 (Пт) 22:05

tyomitch писал(а):Картина чуть-чуть проясняется...
Рэймонд Чен написал статью про WM_QUIT ( http://weblogs.asp.net/oldnewthing/arch ... 78018.aspx ). В её обсуждении я задал сабжевый вопрос, и получил следующие ответы:
Raymond Chen писал(а):I'll return to this topic in a few months.

rrrr писал(а):As far as I know PostQuitMessage sets a flag only and PostThreadMessage posts a real message.

Выводы:
- похоже, моя догадка верна;
- мы скоро узнаем наверняка.

Ура! Чен сдержал обещание! :bounce:
http://blogs.msdn.com/oldnewthing/archi ... 89028.aspx
Изображение


Вернуться в Народный треп

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 108

    TopList