1. 程式人生 > >Windows訊息響應機制之三:執行緒與訊息佇列

Windows訊息響應機制之三:執行緒與訊息佇列

當一個執行緒第一次被建立時,系統假定執行緒不會用於任何與使用者相關的任務。這樣可以減少執行緒對系統資源的要求。但是,一旦該執行緒呼叫一個與圖形使用者介面有關的函式 如檢查它的訊息佇列或建立一個視窗 ),系統就會為該執行緒分配一些另外的資源,以便它能夠執行與使用者介面有關的任務。特別是,系統分配了一個THREADINFO結構,並將這個資料結構與執行緒聯絡起來。 THREADINFO結構體如下: 
1.將訊息傳送到執行緒的訊息佇列當執行緒有了與之聯絡的THREADINFO結構時,訊息就有自己的訊息佇列集合。    通過呼叫函式  BOOL  PostMesssage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)

    可以將訊息放置線上程的登記訊息佇列中。     當一個執行緒呼叫這個函式時,系統要確定是哪個執行緒建立了用 hwnd 引數標識的視窗。然後系統分配一塊記憶體,將這個訊息引數儲存在這塊記憶體中,並將這塊記憶體增加到相應執行緒的登記訊息佇列中。並且該函式還設定QS_POSTMESSAGE喚醒位。函式 PostMesssage 登記了訊息後立即返回,呼叫該函式的執行緒不知道登記的訊息是否被指定視窗的視窗過程所處理。    還可通過呼叫函式  BOOL  PostThreadMesssage(DWORD dwThreadId, UINT uMsg, WPARAM wParam, LPARAM lParam) 
將訊息放置線上程的登記訊息佇列中,同 PostMesssage 函式一樣,該函式在向執行緒的佇列登記訊息後立即返回,呼叫該函式的執行緒不知道訊息是否被處理。     向執行緒的佇列傳送訊息的函式還有 VOID PostQuitMesssage(int nExitCode) ; 該函式可以終止執行緒訊息的迴圈,呼叫該函式類似於呼叫:PostThreadMesssage(GetCurrenThreadId( ), WM_QUIT, nExitCode, 0); 但 PostQuitMesssage 並不實際登記一個訊息到任何佇列中。只是在內部,該函式設定 QS_QUIT 喚醒標誌,並設定 THREADINFO 
結構的 nExitCode 成員。
2.向視窗傳送訊息將視窗訊息直接傳送給一個視窗過程可以使用函式 LRESULT SendMessage( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 視窗過程將處理這個訊息,只有當訊息被處理後,該函式才能返回。即具有同步的特性。     該函式的工作機制: 2.1 如果呼叫該函式的執行緒向該執行緒所建立的視窗傳送了一個訊息,SendMessage 就很簡單:它只是呼叫指定視窗的視窗過程,將其作為一個子例程。當視窗過程完成對訊息的處理時,它向 SendMessage 返回一個值。SendMessage 再將這個值返回給呼叫執行緒。 2.2當一個執行緒向其他執行緒所建立的視窗傳送訊息時,SendMessage 就複雜很多(即使兩個執行緒在同一個程序中也是如此)。windows 要求建立視窗的執行緒處理視窗的訊息。所以當一個執行緒呼叫 SendMessage  向一個由其他程序所建立的視窗傳送一個訊息,也就是向其他執行緒傳送訊息,傳送執行緒不可能處理該視窗訊息,因為傳送執行緒不是執行在接收程序的地址空間中,因此不能訪問相應視窗的過程的程式碼和資料。(對於這個,我有點疑問:同一個程序的不同執行緒是執行在相同程序的地址空間中,它也採用這種機制,又作何解釋呢?)實際上,傳送執行緒要掛起,而有另外的執行緒處理訊息。所以為了向其他執行緒建立的視窗傳送一個視窗訊息,系統必須執行一些複雜的動作。      由於windows使用上述方法處理執行緒之間的傳送訊息,所以有可能造成執行緒掛起,嚴重的會出現死鎖。      利用一下4個函式可以編防寫性程式碼防護出現這種情況。     1. LRESULT SendMessageTimeout( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT fuFlags, UINT uTimeout , PDWORD_PTR pdwResult); 2. BOOL SendMessageCallback( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, SENDSYNCPROC pfnResultCallback,  ULONG_PTR dwData); 3. BOOL SendNotifyMessage( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);  4.BOOL ReplyMessage( LRESULT lResult); 另外可以使用函式 BOOL InSendMessage( ) 判斷是在處理執行緒間的訊息傳送,還是在處理執行緒內的訊息傳送 

相關推薦

Windows訊息響應機制執行訊息佇列

當一個執行緒第一次被建立時,系統假定執行緒不會用於任何與使用者相關的任務。這樣可以減少執行緒對系統資源的要求。但是,一旦該執行緒呼叫一個與圖形使用者介面有關的函式 ( 如檢查它的訊息佇列或建立一個視窗 ),系統就會為該執行緒分配一些另外的資源,以便它能夠執行與使用者介面有關

Windows訊息響應機制PostQuitMessage和GetMessage函式

 Windows是訊息驅動的作業系統。在Windows環境下程式設計必須熟練掌握Windows訊息響應機制。  今天在練習Win32程式設計時碰到一個關於GetMessage函式的問題。這個問題之前一直沒有引起過我的注意,但是今天  在網上搜索發現這個問題很多程式設計師都跟

C++11併發學習執行同步

1.<mutex> 標頭檔案介紹  (1)Mutex系列類(四種) std::mutex,最基本的 Mutex 類。 std::recursive_mutex,遞迴 Mutex 類。 std::time_mutex,定時 Mutex 類。 std::recursive_ti

Java併發程式設計執行掛起、恢復終止的正確方法

出處:http://blog.csdn.NET/ns_code/article/details/17095733 掛起和恢復執行緒 Thread 的API中包含兩個被淘汰的方法,它們用於臨時掛起和重啟某個執行緒,這些方法已經被淘汰,因為它們是不安全的,不穩定的。如果

Linux中斷機制中斷的執行

在核心程式碼中,對X86平臺中斷執行的基本過程是: 1、 通過IDT中的中斷描述符,呼叫common_interrupt; 2、 通過common_interrupt,呼叫do_IRQ,完成vector到irq_desc的轉換,進入Generic int

【Android 開發】: Android 訊息處理機制: Handler 中 sendMessage() 原始碼剖析

  閱讀此文,請先閱讀以下相關連線: sendMessage()的幾種過載方法的使用方式的不同以及它們的原始碼的剖析.   通過前面幾講的內容,我們知道Android不但可以使用非同步任務處理多執行

C++11併發學習執行同步(續)

有時候,在第一個執行緒完成前,可能需要等待另一個執行緒執行完成。C++標準庫提供了一些工具可用於這種同步操作,形式上表現為條件變數(condition variable)和期望(future)。 一.條件變數(condition variable) C++標準庫對條件變數有兩套實現:std::c

工業網際網路平臺核心技術平行計算分散式計算

之所以將兩種計算技術放在一起,是因為這兩種計算具有共同的特點,都是運用並行來獲得更高效能運算,把大任務分為N個小任務。但兩者還是有區別的,關於兩者的區別在後面說。 一、平行計算 1、平行計算概念 平行計算又稱平行計算是指一種能夠讓多條指令同時進行的計算模式,可分為時

Java執行生命週期的控制

任何事物都有一個生命週期,執行緒也不例外。要想控制執行緒的生命,先得了解執行緒產生和消亡的整個過程。請讀者結合前面講的內容,請觀察下圖: 控制執行緒生命週期的方法有多種,如suspend()方法、resume()方法和stop()方法。但是這3個方法都不推薦使用,特別是suspend和

Java執行間的通訊

同屬於一個程序的多個執行緒,是共享地址空間的,它們可以一起協作來完成指定的任務。因此,執行緒之間必須相互通訊,才能完成協作。 一、引入問題 下面通過一個應用案例來講解執行緒間的通訊。把一個數據儲存空間劃分為兩個部分:一部分用於儲存使用者的姓名,另一部分用於儲存使用者的性別。 這個

Python並行程式設計()執行同步Lock

1、基礎概念       當兩個或以上對共享記憶體操作的併發執行緒中,如果有一個改變資料,又沒有同步機制的條件下,就會產生競爭條件,可能會導致執行無效程式碼、bug等異常行為。       競爭條件最簡單的解決方法是使用鎖。鎖的操作非常簡單,當一個執行緒需要訪問部分共享記憶體時,它必須先獲得鎖才能訪問。此執

C++11併發學習執行管理

1.啟動執行緒 (1)使用物件 “小試牛刀”中thread構造時傳入的是函式,還可以傳入物件。 #include <thread> #include <iostream>   void func() {     std::cout<<

java執行學習()執行中斷 interrupt() 方法的使用

上一章節中,我們對執行緒終止stop方法進行了講解,stop終止執行緒的方法已經被丟棄,原因是執行緒的終止太暴力,會導致不必要的資料錯誤,所以stop方法在不自信的情況下,慎用慎用。。。。同時,也提供了較為完善的終止方案了。 本節就來學習執行緒中斷 interrupt() 方法的使用: 一、

DAPMaudio pathsasound.conf

  其實asound.conf真跟dapm沒多大關係,之所以把它也納入dapm系列之一,是為了考慮到知識的連貫性。在<DAPM之二:AUDIO PATHS與dapm kcontrol>提到:通過配置好asound.conf,上層則可開啟asound.conf中

Java執行()執行協作-生產者/消費者問題

        上一篇講述了執行緒的互斥(同步),但是在很多情況下,僅僅同步是不夠的,還需要執行緒與執行緒協作(通訊),生產者/消費者問題是一個經典的執行緒同步以及通訊的案例。該問題描述了兩個共享固定大小緩衝區的執行緒,即所謂的“生產者”和“消費者”在實際執行時會發生的問題。

玩轉大資料系列資料報表展示

經過了資料採集與資料同步、資料分析和處理,我們應該考慮將處理好的資料做成報表或者大屏展示給老闆們看,以便老闆們可以更加精準地做出戰略決策,為業務的發展指明方向。 提到資料報表,不得不說說Quick BI。Quick BI提供海量資料實時線上分析服務,支援拖拽式操作、提供了豐富的視覺化效果,可以幫助您輕鬆自如

執行學習執行池ThreadPoolExecutor Executors

/**      * Creates a new {@code ThreadPoolExecutor} with the given initial      * parameters.      *      * @param corePoolSize the

python執行

執行緒鎖:當多個執行緒同時進行任務時,為保證不會有多個執行緒對同一個資料進行操作造成不可預料的後果,加個鎖,將此時的線         程變為單執行緒進行操作。threading_Lock()四個狀態:1、獲取鎖、上鎖:acquire()                 2、

java畫圖板——用執行讓多個小球在介面自動運動

在介面上,除了可以實現點選,滑鼠移動等操作的監聽器,還有可以自動執行的執行緒 執行緒是指令執行的最小單位,而且多個執行緒是共用一個程序的記憶體的,也就是說我們在一個程式中可以開很多個執行緒,不過執行緒開多了當然佔用的記憶體就多 現在我們要實現的是,執行主程式

Java多執行執行池和Executors類解析

執行緒池 多執行緒技術主要解決處理器單元內多個執行緒執行的問題,它可以顯著減少處理器單元的閒置時間,增加處理器單元的吞吐能力。 假設一個伺服器完成一項任務所需時間為:T1 建立執行緒時間,T2 線上程中執行任務的時間,T3 銷燬執行緒時間。 如果:T1 +