SendMessage發送的消息不進入消息隊列嗎

轉載:http://www.cnblogs.com/trxdy/p/3381270.html

對線程間SendMessage的解疑

上面說過線程內SendMessage只是簡單的調用指定窗口的窗口過程。

而線程間SendMessage時,發送線程不可能直接調用目標窗口的窗口過程,因爲發送線程無法運行在接收線程的地址空間中。因此實際過程是發送線程掛起,然後由另外的線程處理消息。過程是:

首先發送的消息被追加到接收線程的發送消息隊列中(send-message queue),並設置線程的QS_SENDMESSAGE標誌。這個隊列跟郵遞消息隊列(post-message queue,即之前所謂的消息隊列)是並列的,之間沒有關係。另外還有一個應答消息隊列(reply-message queue),這在後面會用到。

之後,如果接收線程已經在執行其它代碼,則暫時不會處理該消息。當接收線程進入等待消息時(如調用GetMessage、PeekMessage或WaitMessage),Windows系統首先檢查線程的QS_SENDMESSAGE喚醒標誌是否設置,如果設置,則系統掃描發送消息隊列中消息的列表,並找到第一個發送的消息。

當接收線程等待消息時,系統從發送消息隊列中取出第一個消息並調用相應的窗口過程來處理消息。如果發送消息隊列中不再有消息,則QS_SENDMESSAGE被關閉。當接收線程處理消息時,調用SendMessage的線程設置成idle狀態,並等待一個消息出現在它的應答消息隊列中。在發送的消息處理之後,窗口過程的返回值等級到發送線程的應答消息隊列中。發送線程被喚醒,取出包含映帶消息隊列中的返回值,即SendMessage的返回值。然後發送線程繼續執行。

當線程等待SendMessage返回時,基本時處於idle狀態。但當其它線程向該線程的窗口發送消息時,系統要立即處理消息,而不用象前一段說過的等待線程調用GetMessage、PeekMessage或WaitMessage時才處理線程間的Send消息。

雖然線程間的非隊列(Send)消息也是發送的隊列中的,但與post消息有兩個主要區別:

1.隊列不同,分別是send-message queue和post-messag queue。

2.獲取消息途徑不同。Post型消息是接收線程通過GetMessage獲得的;而Send型消息則是通過系統從隊列中提取,然後調用該消息的對應窗口進行執行,這個過程在接收線程等待消息時才執行。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章