MiniGUI Lite 版本的新改进
簡介:?MiniGUI從0.98開始推出Lite版本。Lite版本是MiniGUI邁向嵌入式應(yīng)用重要的一步。在Lite版本中,我們使用了自己設(shè)計(jì)的引擎,拋棄了pthread庫,從而使得MiniGUI能夠輕裝上陣,更穩(wěn)定,更高效率,也更符合嵌入式系統(tǒng)應(yīng)用。本文介紹了MiniGUILite版本的基于UnixIPC實(shí)現(xiàn)的多進(jìn)程機(jī)制。并詳細(xì)介紹了一些實(shí)現(xiàn)細(xì)節(jié)。
?
1 引言:為什么要開發(fā)Lite版本
現(xiàn)在,大多數(shù)UNIX系統(tǒng)采用X 窗口系統(tǒng)作為圖形用戶界面,MS Windows 則采用 Microsoft公司自己設(shè)計(jì)的GUI系統(tǒng)。這兩種GUI系統(tǒng)也代表著目前通用GUI系統(tǒng)的兩種實(shí)現(xiàn)。比如,著名的自由軟件MicroWindows就同時(shí)實(shí)現(xiàn)了類似于MS Windows的MicroWindows API 和類似于X Window的NanoX API。
MiniGUI 原來就采用了類似于MS Windows的體系結(jié)構(gòu),并且建立了基于線程的消息傳遞和窗口管理機(jī)制。然而,它是基于POSIX 線程的,這種實(shí)現(xiàn)提供最大程度上的數(shù)據(jù)共享,但也同時(shí)造成MiniGUI體系結(jié)構(gòu)上的脆弱。如果某個(gè)線程因?yàn)榉欠ǖ臄?shù)據(jù)訪問而終止運(yùn)行,則整個(gè)系統(tǒng)都將受到影響。
另一種方法是采用UNIX進(jìn)程間通信機(jī)制建立窗口系統(tǒng),即類似 X Window 的客戶/服務(wù)器體系。但是這種體系結(jié)構(gòu)也有它的先天不足,主要是通常的 IPC 機(jī)制無法提供高效的數(shù)據(jù)復(fù)制,大量的 CPU 資源用于各進(jìn)程之間復(fù)制數(shù)據(jù)。在 PDA 等設(shè)備中,這種 CPU 資源的浪費(fèi)將最終導(dǎo)致系統(tǒng)性能的降低以及設(shè)備耗電量的增加。
為了解決以上各種問題,同時(shí)也為了讓 MiniGUI更加適合于嵌入式系統(tǒng),我們開發(fā)了MiniGUI Lite 版本。
2 Lite版本簡介
在MiniGUI Lite 版本中,我們可以同時(shí)運(yùn)行多個(gè) MiniGUI 應(yīng)用程序。首先我們啟動(dòng)一個(gè)服務(wù)器程序 mginit,然后我們可以從中啟動(dòng)其他做為客戶運(yùn)行的 MiniGUI 應(yīng)用程序。如果因?yàn)槟撤N原因客戶終止,服務(wù)器可以繼續(xù)運(yùn)行。mginit程序建立了一個(gè)虛擬控制臺(tái)窗口。我們可以從這個(gè)虛擬控制臺(tái)的命令行啟動(dòng)其他的程序,甚至可以通過 gdb 調(diào)試這些程序。 這大大方便了MiniGUI應(yīng)用程序的調(diào)試。
MiniGUI-Lite 區(qū)別于 MiniGUI 原有版本的最大不同在于我們可以在 MiniGUI-Lite 程序中創(chuàng)建多個(gè)窗口,但不能啟動(dòng)新的線程建立窗口。除此之外,其他幾乎所有的 API 都和 MiniGUI 原有版本是兼容的。因此,從 MiniGUI 原有版本向 MiniGUI-Lite 版本的移植是非常簡單的。象mglite-exec 包中的程序,其中所有的程序均來自 miniguiexec 包,而每個(gè)源文件的改動(dòng)不超過 5 行。
3 Lite版本的設(shè)計(jì)
設(shè)計(jì)之初,我們確定MiniGUI Lite 版本的開發(fā)目的:
顯然,要滿足這三個(gè)設(shè)計(jì)目的,如果采用傳統(tǒng)的 C/S 結(jié)構(gòu)對(duì)現(xiàn)有 MiniGUI 進(jìn)行改造,應(yīng)該不難實(shí)現(xiàn)。但傳統(tǒng) C/S 結(jié)構(gòu)的缺陷卻無法避免。經(jīng)過對(duì) PDA 等嵌入式系統(tǒng)的分析,我們發(fā)現(xiàn),某些 PDA 產(chǎn)品具有運(yùn)行多個(gè)任務(wù)的能力,但同一時(shí)刻在屏幕上進(jìn)行繪制的程序,一般不會(huì)超過兩個(gè)。因此,只要確保將這兩個(gè)進(jìn)程的繪制相互隔離,就不需要采用復(fù)雜的 C/S 結(jié)構(gòu)處理多個(gè)進(jìn)程窗口之間的互相剪切。在這種產(chǎn)品中,如果采用基于傳統(tǒng) C/S 結(jié)構(gòu)的多窗口系統(tǒng),實(shí)際是一種浪費(fèi)。
因此,我們對(duì) MiniGUI-Lite 版本進(jìn)行了如下簡化設(shè)計(jì):
4 Lite版本的一些實(shí)現(xiàn)細(xì)節(jié)
4.1 系統(tǒng)初始化
應(yīng)用程序的入口點(diǎn)為main()函數(shù),而MiniGUI應(yīng)用程序的入口點(diǎn)為MiniGUIMain,在這兩個(gè)入口點(diǎn)之間,是MiniGUI的初始化部分和結(jié)束部分。如圖 1所示。
圖 1 MiniGUI應(yīng)用程序流程
在系統(tǒng)初始化時(shí),MiniGUI區(qū)分兩種情況:服務(wù)器(Server)和客戶(Client)。針對(duì)這兩種不同的情況,隨后的各項(xiàng)操作均有不同的處理,這主要依據(jù)全局變量mgServer。由于僅僅根據(jù)名稱判斷是否為服務(wù)器,所以服務(wù)器的名字只能是"mginit"。 InitGUI()是對(duì)MiniGUI進(jìn)行初始化的函數(shù),它主要負(fù)責(zé):
流程如圖 2(為突出重點(diǎn),我們忽略了一些細(xì)節(jié)):
圖 2 InitGUI流程
4.2 共享資源初始化
共享資源是客戶服務(wù)器模型中的重要元素,它由服務(wù)器負(fù)責(zé)創(chuàng)建和釋放,而提供所有客戶程序共享的數(shù)據(jù)資源。它的初始化過程由圖 3所示的調(diào)用流完成。
圖 3 InitGUI調(diào)用流
如果是服務(wù)器,則初始化此結(jié)構(gòu),src/kernel/sharedres.c/LoadSharedResource()負(fù)責(zé)完成這一任務(wù),它的執(zhí)行流如圖 4所示:
圖 4 LoadSharedResource 流程
對(duì)于客戶,則只需要與此結(jié)構(gòu)進(jìn)行連接即可,它在src/kernel/sharedres.c/AttachSharedResource()實(shí)現(xiàn),參見圖 5:
圖 5 AttachSharedResource 流程
4.3 服務(wù)器客戶通信連接初始化
在客戶服務(wù)器模型的討論中,我們還將詳細(xì)的討論服務(wù)器客戶的通信機(jī)制,這里只給出初始化的調(diào)用關(guān)系。見圖 6。
圖 6 通信連接的初始化
ServerStartUp實(shí)現(xiàn)流程如圖 7所示:
圖 7 ServerStartUp 流程
ClientStartUp()實(shí)現(xiàn)如圖 8所示:
圖 8 ClientStartUp流程
4.4 多進(jìn)程模型
Lite版本是支持客戶服務(wù)器(C/S)方式的多進(jìn)程系統(tǒng),在運(yùn)行過程中有且僅有一個(gè)服務(wù)器程序在運(yùn)行,它的全局變量mgServer被設(shè)為TRUE,其余的MiniGUI應(yīng)用程序?yàn)榭蛻?#xff0c;mgServer變量被設(shè)為FALSE。各個(gè)應(yīng)用程序分別運(yùn)行于各自不同的進(jìn)程空間,如圖 9所示:
圖 9 多進(jìn)程模型
目前的程序結(jié)構(gòu)使每個(gè)加載的進(jìn)程擁有一個(gè)自已的桌面模型及其消息隊(duì)列,進(jìn)程間的通信依靠以下所提到的進(jìn)程通信模型來完成。
4.5 進(jìn)程通信模型
這里我們所指的進(jìn)程通信包括通過共享內(nèi)存實(shí)現(xiàn)的數(shù)據(jù)交換和通過套接字實(shí)現(xiàn)的客戶服務(wù)器通信模型。先看在MiniGUI中使用Socket的通信模型結(jié)構(gòu),如圖 10:
圖 10 基于Socket 的通信模型
下面再看看MiniGUI進(jìn)程間的資源共享問題。見圖 11。
圖 11 內(nèi)存共享通信模型
如上圖所示,服務(wù)器負(fù)責(zé)裝入共享資源,其中包括系統(tǒng)圖標(biāo)、位圖、字體等,客戶則通過AttachSharedResource()獲取指向共享資源的指針,初始化一塊共享內(nèi)存及與使用已有共享內(nèi)存的方法在前面的描述中已提到,在此不再贅述。
4.6 各進(jìn)程之間的同步
這里所指的進(jìn)程同步主要是指各進(jìn)程繪制的同步,顯然,同時(shí)不可能有兩個(gè)進(jìn)程向屏幕繪制。傳統(tǒng)的GUI實(shí)現(xiàn)大多是只有一個(gè)進(jìn)程負(fù)責(zé)繪制,而在我們Lite版本中,各進(jìn)程負(fù)責(zé)自己的繪制。同時(shí),我們的Lite 版本還支持虛屏切換,當(dāng)我們切換出去的時(shí)候,誰也不能夠向屏幕繪制。
Lite 版本利用Unix 信號(hào)解決了繪制同步問題。系統(tǒng)定義了兩個(gè)信號(hào):SIG_SETSCR 和 SIG_DNTDRAW,它們其實(shí)是重定義了的信號(hào)SIGUNUSED和 SIGSTKFLT。每個(gè)進(jìn)程都定義了兩個(gè)變量dont_draw和cant_draw。
服務(wù)器利用SIG_SETSCR和SIG_DNTDRAW來控制各客戶程序誰有權(quán)對(duì)屏幕繪制,而不是自己全權(quán)代理。這也使得進(jìn)程間通信量大大減少:當(dāng)服務(wù)器希望一個(gè)客戶程序不要向屏幕繪制時(shí),就向它發(fā)送SIG_DNTDRAW信號(hào),當(dāng)讓其繪制時(shí),則發(fā)送SIG_SETSCR。從而實(shí)現(xiàn)了各進(jìn)程間的屏幕繪制同步。
當(dāng)一個(gè)客戶收到SIG_DNTDRAW時(shí),將自己的變量dont_daw設(shè)置為ture,收到SIG_SETSCR時(shí),則將dont_draw變量設(shè)置為false。另一個(gè)變量cant_draw則是給客戶自己用的,比如,做剪切時(shí),當(dāng)它的剪切域?yàn)榭占瘯r(shí),又比如,當(dāng)進(jìn)行虛屏切換時(shí),當(dāng)前的進(jìn)程將自己的cant_draw變量設(shè)置為true。
另外,如果一個(gè)客戶正在繪圖,我們只有等它畫完后才能讓其他進(jìn)程得到這一權(quán)利。我們不需要知道誰在繪圖,但我們要等到這一過程結(jié)束。Lite版本利用信號(hào)量機(jī)制解決了這一問題。在共享內(nèi)存里保存著一個(gè)變量shmid,各進(jìn)程利用它來實(shí)現(xiàn)各自的鎖機(jī)制。這種機(jī)制有點(diǎn)類似于文件鎖,不過要快許多。
從而,利用信號(hào)量機(jī)制,Lite版本實(shí)現(xiàn)了多進(jìn)程的繪制同步。服務(wù)器利用信號(hào)控制各客戶,而各客戶也充分合作。相關(guān)代碼都在MiniGUI的系統(tǒng)庫里實(shí)現(xiàn)。保證了系統(tǒng)的穩(wěn)定運(yùn)行。
5 總結(jié)語
MiniGUI Lite版本試圖在傳統(tǒng)的基于線程的單體結(jié)構(gòu)和C/S結(jié)構(gòu)之間尋求一種效率和穩(wěn)定性的折中,以便更加適合運(yùn)行在PDA等小型嵌入式系統(tǒng)中。如今,MiniGUI Lite版本已經(jīng)穩(wěn)定地運(yùn)行在一些PDA系統(tǒng)上,事實(shí)證明這種嘗試是成功的。
參考資料
- MiniGUI 資源
- MiniGUI 主頁
總結(jié)
以上是生活随笔為你收集整理的MiniGUI Lite 版本的新改进的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 股票常用名词解释与技术指标公式
- 下一篇: C4D 入门笔记(二)