1. 程式人生 > >訊息機制在軟體設計中的應用

訊息機制在軟體設計中的應用

訊息機制是個實用的東西,不知道是何人發明,個人見識較少,最早見於WIN32程式設計,關鍵的幾句程式碼大約是:
while(GetMessage (&msg, NULL, 0, 0))
       
{       
    TranslateMessage (&msg) ;
       
    DispatchMessage (&msg) ;
       
}這就是WIN32訊息機制的最核心了,雖然當時對這種頗為神奇的機制不甚瞭解,但卻好奇,這裡的訊息從哪裡來,TranslateMessage做了什麼工作,為什麼不能省略掉,DispathMessage又做了什麼工作,訊息又被送到哪裡去了?如今基礎稍微好點的VC程式設計師應該都能回答這幾個問題,但是,微軟設計出來的這個訊息系統為什麼會是看到的這個樣子?有什麼必然的原因麼?

訊息其實是對人類社會資訊傳遞的一種極好的抽象,語言傳遞的是訊息,信件傳遞的也是訊息。

訊息機制目前為止應用的最為廣泛的領域估計依然是視窗系統,各種各樣的GUI系統幾乎都以自己的方式實現了對訊息的處理,當然,不全是WIN32這個樣子,如將回調函式直接註冊到訊息源通過回撥實現響應的方法也被廣泛採用。


                             圖1

其實,類似WIN32這樣的訊息機制經過適當的裁剪或者改造,可以應用在許多不同的場合。

應用示例1:
   微控制器系統,許多的微控制器的運作邏輯都可以概括為響應事件的觸發,並對輸出做一定的調節,這個觸發條件就可以被視為訊息的輸入,在具有LCD面板等人機介面的微控制器系統中,基本上可以完全移植WIN32的訊息機制進行處理而達到類似於合作式作業系統的效果。如下圖:

                             圖2


在如上圖中,按鍵檢測ISR,timer ISR,外部中斷ISR為三個中斷服務程式,在這三個ISR中只完成時間相關度相對高的操作,然後將事件訊息放入訊息佇列,供主程式處理,單就這個處理方式來說,雷同於linux 中的tasklet機制,即將中斷分為上下兩部分,上部分處理硬體相關或者實時性強的操作,後半部分進行較大量的資料處理。在主程式的while迴圈中,不停的從訊息佇列獲取訊息,如有必要則對訊息進行翻譯或者整理,然後根據全域性狀態機或者GUI系統自己的父子視窗等機制確定訊息流向,找到並呼叫相關的處理函式,通常,這裡還需要一個Default_proc提供一些系統預設的訊息處理方法。在如上的一個系統中,如果把每一個 wnd_proc看做一個任務的話,則任務切換的時刻發生在每個任務執行結束之時,或者說每個任務主動放棄執行權的時候,其效果也就類似於合作是排程的作業系統了,這樣的實現方式對外部事件的響應能力明顯強過典型的whie(1)結構,和實時作業系統相比,在基本不需要同步機制的情況下得到了有限的實時性,結構清晰,容易控制。

應用示例2:
 仔細分析圖1會發現,整個系統其實是一個典型的“分----總------分”結構,兩個“分”是說有多個輸入,也有多個輸出,一個“總”是說多個輸入和輸出都要服從一個統一的調配和管理。這樣的系統恰好本人在最近遇到一個,該系統的要求如下:
1. 有多個觸發輸入,包括:移動偵測,RF位置觸發偵測,遙控開關輸入,外部數字觸發,視訊丟失
其中在RF觸發偵測中還夾雜著燈光遙控功能,每一種輸入要能單獨使能。
2. 有多個觸發輸出,包括:JPEG抓拍,ASF錄影,FTP錄影傳送,MAIL傳送JPEG檔案,MAIL傳送純文字資訊,SMS短訊通知,PTZ攝像機定位,數字報警輸出,聲音報警輸出,每一種輸出要能單獨使能,最好能針對每一種觸發輸入單獨使能。
3. 整個系統要能整體開關。

分析整個系統,稍微改造一下圖1的框架就可以應用於這個系統,具體實施過程如下:
1. 在各個觸發檢測執行緒內提交觸發訊息
2. 在訊息提取迴圈中完成訊息的翻譯和對輸入的資訊的過濾,如:將提交的RF觸發訊號翻譯為特定的觸發位置,關閉整個系統等。
3. 為每個訊息建立對應的處理函式和輸出功能表,將觸發輸出函式動態的註冊到相應的表中,實現觸發輸出的動態調整。
最終建立框架如下: