摘 要:桌面系統由一系列應用程序組成,它們之間需要協作一致來完成特定的任務,這就要求應用程序能夠高效、快速地進行通信。由于傳統IPC機制和遠程互操作體系并不適應桌面進程通信的要求,因此在開放系統領域中處于主流地位的桌面系統GNOME和KDE分別采用CORBA和DCOP作為桌面進程通信機制。一種新的用于統一各個不同桌面的進程通信機制DBUS也被制定出來。通過對各種通信機制進行分析和比較,抽象桌面進程通信的基本架構和特點,總結出設計和選擇桌面進程通信機制的基本原則。
關鍵詞:桌面進程通信;CORBA;DCOP;DBUS
中圖法分類號:TP136.81 文獻標識碼:A 文章編號:1001-3695(2006)10-0194-04
Research on Desktop InterProcess Communication of Open System
CHEN Huaqing,WU Jian
(Institute of Software, Chinese Academy of Sciences, Beijing 100080, China)
Abstract:The desktop system is composed of a collection of application programs which need to collaborate with each other to accomplish a special task. So the programs should communicate effectively and rapidly. Owe to the traditional IPC mechanism and Interoperate system isn’t fit for the desktop InterProcess Communication(IPC), GNOME and KDE which are primary desktop system in open system adopt CORBA and DCOP as there communication mechanism respectively and DBUS which intent for used in all the desktop is designed recently. In this paper, we acquire the architecture and characteristics of the desktop IPC and also put forward a principle of design and how to choose a desktop IPC by analyze and compare these desktop IPC mentioned above.
Key words:Desktop InterProcess Communication;CORBA;DCOP;DBUS
1 引言
在計算機人機界面的設計上,曾經有過許多方案,現在處于主流地位的是圖形用戶界面(GUI)。在個人電腦桌面領域主要的操作系統MS Windows,Apple MacOS,Linux均提供了圖形化的用戶桌面,不過它們的實現方式并不相同。與Windows不同,廣泛用于開放操作系統Linux的圖形用戶界面X Window并不是操作系統內核的一部分,因此方便了第三方桌面系統的開發。在基于X Window 和Xlib的基礎上,目前存在多個用于開放操作系統的開源桌面系統,其中最流行的是GNOME和KDE。
桌面環境是一系列程序的集合,每一個程序均針對一個特定的任務。雖然用戶需要完成的任務具有很大的差異性,但是桌面系統的主要目標是為用戶提供一個規范和統一的方法,以方便用戶能有效地使用計算機提供的各種功能和資源。完成這一目的需要在傳統的Linux/UNIX窗口管理器的基礎上集成那些已有的工具和軟件,桌面進程間需要通過相互通信來協作一致地完成相關任務以滿足用戶的需求。以下是進程間需要通信的一些例子[1]:①桌面需要為應用程序的啟動動態地提供反饋。②現代的操作系統常常需要使用桌面瀏覽器來處理URL,或者調用桌面的標準郵件程序來處理郵件。③當用戶在應用程序外部更改設置時,系統必須通知應用程序在行為和外觀上作必要的修改。④用戶使用代理服務向一個遠程程序發送命令。⑤當啟動一個單例程序(系統中只能運行一個實例)時,如果該程序已經運行,則通過一個對話框反饋給用戶。
2 背景和現狀
Linux提供了很多進程間的通信機制,有管道、套接字、遠程方法調用、臨時文件、X原子、信號量、消息隊列和共享內存等。它們各自適用于不同的情況:使用管道的兩個進程必須相關;套接字和遠程方法調用適合在網絡中位于不同計算機上的進程之間的通信;信號量主要解決同步互斥問題;消息隊列用于內核與各組件間的通信[2];X原子使X窗口系統中的應用程序間或程序與X Server之間在傳遞數據上非常方便,然而X原子機制在傳送數據大小方面有著固有的限制,并且缺乏靈活性和傳遞復雜信息的能力。雖然它們在Linux系統中已經得到廣泛應用,但是由于桌面環境的特點,這些進程通信機制大都只適合應用在同構的環境中,而且當系統中有多個應用程序相互通信時,開發者將面臨著復雜的拓撲結構,系統的可靠性和可維護性也成了問題,所以這些傳統的進程通信機制在桌面進程通信中并不適用。
目前,在網絡、中間件以及分布式計算等領域,已經提出并得到廣泛支持的互操作技術有DCOM,CORBA,J2EE,Web服務以及最新提出的ICE(網絡通信引擎)和ACE(自適配通信環境)。這些互操作技術雖然也可用于桌面進程通信,但是由于它們為適應進程間遠程通信的需要而制定的復雜通信協議所帶來的相對桌面進程通信的巨大開銷,使得它們并不適用于桌面進程通信。
根據以上分析,需要為Linux的桌面環境制定一個新的符合桌面應用需要的進程通信機制。Linux桌面環境的特點要求桌面進程間通信機制必須具備以下特點[3]:①進程間通信必須是高效的、輕量的。②新的通信機制能夠方便地整合到現有的應用程序中,并且盡量減少開發者不必要的負擔。③必須具備網絡透明性,對用戶隱藏協議實現的復雜性,傳輸層對用戶來說是不可見的。④易于開發者掌握。其中第一條是最重要的要求,因為桌面環境主要是提供與用戶交互的接口,要求能迅速響應用戶的要求。根據這些特點,Linux的主流桌面系統KDE(被紅旗Linux,SuSE Linux所采用)和GNOME(被RedHat,Debian Linux,Solaris所采用)各自制定了不同的桌面進程通信機制。但是由于這兩種桌面系統的進程通信機制不同,使得不同桌面系統中的程序互操作仍存在困難,因此一個新的用于統一不同桌面環境中桌面進程通信機制的標準DBUS被制定出來并逐步在Linux桌面中得到應用。
3 GNOME的桌面進程通信機制
CORBA是一種已經得到廣泛應用的以通信機制為核心的體系結構,GNOME桌面進程通信機制和組件模型Bonobo均建立在CORBA的基礎上。GNOME是基于GTK+庫用C語言實現的,所以主要使用CORBA到C語言的映射。GNOME中CORBA ORB的實現稱為ORBit,它是專門針對GNOME桌面環境的特點用C語言實現的一個高效ORB,符合CORBA 2.4標準,提供了對C/C++,Python,Perl等許多語言的綁定,通過其GNOME的應用程序可以實現很好的交互。
GNOME的CORBA架構如圖1所示。
GNOME客戶程序通過命名服務或IOR字符串來獲得要訪問的服務對象引用,然后發送請求調用GNOME服務對象實現提供的服務。如果服務對象在客戶端有相應的IDL接口定義的存根代碼,則客戶程序可以通過IDL存根向服務實現對象發送請求(靜態調用);否則客戶程序可以通過在接口倉庫中匹配服務對象的接口信息后,利用動態調用接口來向實現對象發送請求(動態調用)。當服務請求通過ORB接口到達ORBit后,ORBit將請求轉發給服務對象實現。服務對象端由對象適配器接收服務請求,如果請求的服務對象有IDL框架,則通過IDL框架調用服務實現對象的方法;否則通過動態框架接口來調用服務實現對象中的方法。請求調用的服務實現對象的方法結束后,方法的運行結果將按對象請求的傳遞路徑逆向返回給客戶對象。
GNOME在很多地方均使用到了CORBA,如文件管理器、面板、窗口管理器和 Bonobo 均使用 CORBA 來實現在應用程序之間清晰的接口。GNOME的桌面中絕大多數應用既是CORBA的Server,同時也有自己的GUI,即它們提供的服務(通過接口提供的方法)需要以圖形界面供用戶訪問它們的服務[4]。為了方便GNOME應用輕松地使用CORBA(ORBit),GNOME提供Gnorba庫對CORBA的復雜性進行封裝。Gnorba主要包括三個部分:初使化,將ORBit的事件循環集成到GTK的事件循環中;命名服務,用于客戶端來獲得要訪問的服務對象引用;GOAD(GNOME活動對象目錄),用來存放處于活動狀態的服務實現對象。此外Gnorba還提供了很多標準的接口,如工廠、引用計數等。
CORBA是一套比較成熟的規范,已經得到廣泛的應用,并得到OMG及眾多廠商的支持。采用CORBA作為桌面進程通信機制使得GNOME可以較好地與其他系統交互(如GNOME桌面可以通過CORBA與OpenOffice的組件模型UNO進行橋接)。但是,相對桌面環境,CORBA是一個復雜的、重量級的協議,需要占用較多的系統資源,而且難以掌握,加大了開發人員的工作難度。
4 KDE的桌面進程通信機制
KDE最初也采用CORBA作為進程通信機制,但是由于CORBA存在以上討論中提及的問題,其在桌面上的表現并不能達到KDE開發人員所期望的效果;KDE還曾采用XMLRPC作為通信機制,但XML的序列化和解析需要占用較多的CPU時間,于是KDE提出了DCOP桌面通信協議來用于進程間通信。DCOP 是一個建立在套接字基礎上的輕量級的進程間通信機制,由于ICE是X11R6中的標準部分,在技術上比較成熟,而且ICE庫不需要運行X服務器,所以DCOP采用ICE(客戶間交換機制)用于通信。DOCP結構如圖2所示。
在DCOP架構中,每一個需要通信的成員均必須成為DCOP的客戶端。當DCOP服務器開始一個桌面會話時就一直運行并扮演著一個消息轉發者的角色,它負責處理屬于這個會話中所有程序之間的通信。當一個程序需要與另一個程序通信時,它就向DCOP服務器發送一個請求;然后DCOP服務器將這個請求轉發給它所要通信的目的程序,目的程序處理請求后將結果返回給DCOP服務器;最后由DCOP服務器將結果返回給發送請求的程序。通過DCOP服務器的通信過程對用戶來說是透明的。
為與其他程序通信,應用程序必須向外界提供一組接口,并且應用程序還需向DCOP服務器注冊應用程序和它所提供的接口。DCOP提供了用于查看所注冊的接口和接口內方法的函數,同時KDE也提供了一組工具(命令行DCOP和可視化工具KDCOP)來查看已注冊的應用程序接口及其方法,以方便DCOP接口的調用。客戶程序可通過函數調用、DCOP信號、DCOP工具來訪問其他客戶程序通過DCOP接口所提供的服務。
DCOP客戶程序可以直接(使用最原始的DCOP方法——Send(),Call()和Process()手工實現DCOP機制)或通過接口向服務程序發送請求。DCOP接口是一個在頭文件中聲明C++類,通過DCOP所定義的一些預處理符號(K_DCOP,K_DCOP)來標志接口向外界提供的方法。KDE提供一個專門用來編譯DCOP接口文件的工具DCOPIDL,其功能與CORBA,COM的IDL編譯器類似。DCOP接口文件通過DCOPIDL編譯后為DCOP客戶程序產生存根(用于客戶端)和框架(用于服務端)文件,與RPC類似,DCOP客戶對DCOP接口的調用是通過存根和框架來完成的。與直接請求相比,通過使用DCOP接口使得DCOP客戶間的通信變得簡單、規范,而且可以由系統自動完成通信數據的串行化和還原,簡化了DCOP通信程序的開發。
DCOP作為一種輕量級的、高效的IPC機制,通過測試能夠滿足桌面環境下程序間快速通信的要求,同時DCOP也可以應用在進程內組件(KParts)之間的通信[5],方便了KDE應用程序的整合。DCOP也有其缺點,即當應用程序之間通過DCOP傳遞大量數據時需要經過兩次傳送。第一次是發送端將數據傳送到DCOP服務器;第二次是由服務器將數據傳送到接收端,所以有較大的時間延遲。這對多媒體應用程序間通信傳遞大量的多媒體數據是不適用的,為此KDE專門制定了一個新的通信協議MCOP來用于多媒體程序間的通信。當DCOP應用在進程內組件之間的通信時,它通過一種特殊的機制,而不通過DCOP服務器直接進行通信來提高效率。由于DCOP是依賴于QT和KDE的,所以并不能用于其他桌面環境。
5 統一的桌面進程通信機制DBUS
由于GNOME和KDE桌面系統所采用的進程通信機制CORBA和DCOP的局限性,它們均只適合各自的桌面環境。為了將CORBA和DCOP替換為簡單的 IPC,并集成這兩種桌面環境,一種新的進程通信機制DBUS被制定出來。與DCOP和GNOME的CORBA實現較多地依賴具體的桌面環境不同,DBUS只需要較少的依賴,因此可以很方便地集成到其他環境中。
DBUS程序通信結構如圖3所示。
DBUS通信協議可以分為三個抽象層次[6]:①底層支持庫Libbus,通過Libbus應用程序可以直接而不通過消息總線進行通信;②消息總線,建立在Libbus的基礎上,是應用程序進行通信的中介;③上層封裝庫,在具體開發環境下(如QT,GTK,Python),語言對Libbus的封裝,它隱藏了Libbus的復雜性,使得使用DBUS變得更加容易。
DBUS系統提供兩種類型的消息總線:①系統總線,它在引導時就會啟動。這個總線由操作系統和后臺進程使用,安全性非常好;②會話總線,它在用戶登錄系統時自動啟動,處于這個會話中的應用程序均可以通過該總線來進行通信。一個應用程序需要接收來自系統總線的消息,它可以直接連接到系統總線,不過它可以發送的消息將是受限的。
應用程序可以不通過消息總線直接通信,但是當系統中存在多個需要相互通信的程序時,連接數將以O(n2)增長,而且不利于連接的管理;使用消息總線作為中介,雖然性能上會有所降低,但連接數大大降低為O(n),而且易于管理。應用程序通過消息總線進行通信時,必須首先與消息總線進行連接,消息總線分配給這個連接一個唯一的標識符。消息總線維護著一個標識符到連接的映射表,可以通過標識符查找到相關的連接。一旦應用程序連接到消息總線上,它就向消息總線添加匹配器來聲明它所希望收到的消息。匹配器可以為基于接口、對象路徑和方法進行接收的消息指定一組規則。由消息總線負責消息的路由,將相互通信的程序連接起來。消息總線對連接數量具有一定的限制,保證了消息通信的性能。
DBUS的消息由消息頭和消息體組成。消息好比一個數據包,消息頭指定地址等控制信息,消息體包含具體數據信息。消息傳送系統根據消息頭的信息進行路由并對消息進行解釋。消息體由零個或多個參數組成。每個消息均有一個源和一個目的地址,這些地址被指定為對象路徑。所有使用 DBUS 的應用程序均包括一組對象,消息發送到或者發送自特定對象,而不是應用程序,這些對象由對象路徑來標志。在 DBUS 中有四種類型的消息[5],即方法調用(Method Calls)、方法返回(Method Returns)、信號(Signals)和錯誤(Errors)。要執行 DBUS 對象的方法時,向對象發送一個方法調用消息。它將完成一些處理并返回一個方法返回消息或者錯誤消息。信號的不同之處在于它們不返回任何內容:既沒有“信號返回”消息,也沒有任何類型的錯誤消息,而且在消息頭中一般不指定目的地址,由系統按照匹配規則進行轉發。
作為一個桌面進程通信協議,DBUS具有如下優點:低延遲而且低開銷,設計得小而高效,以便最小化傳送的往返時間;協議是二進制,而不是文本的,這樣就排除了費時的序列化過程;支持異步通信;提供完善的安全通信機制,而且連接是可靠的、穩定的;語法類似DCOP,并提供到許多語言的綁定,易于使用。由于DBUS在安全性和數據驗證等方面的消耗,Libbus在性能上遜于GNOME的ORBit,DBUS也比DCOP要慢,而且CORBA和DCOP在桌面上已經得到廣泛應用,并有相關組件技術Bonobo和KParts的支持,相對而言,DBUS只是一個純粹的通信協議,目前應用還比較少。
6 桌面進程通信機制總結與思考
桌面通信機制也是一種互操作體系,不過由于它主要是用于在單機環境中進程間的通信,所以它與RPC、基于RPC的互操作體系(DCOM,CORBA,Java RMI等)、XMLRPC、Web服務等互操作體系不同,具有自己的特性。通過對以上通信機制的分析和比較,我們可以得到桌面通信機制的一些共性,它主要由進程通信協議、通信接口定義語言、通信查找方式組成[7]。它們之間的層次、與進程通信實現的對應關系,以及與低層次協議之間的關系如圖4所示。
底層協議是進程間通信所依賴的底層傳輸機制,在網絡環境下一般為TCP/IP協議;在單機中一般為操作系統內核所提供的套接字。
進程通信協議是進行通信的桌面程序關于消息中數據格式、消息類型等方面的約定。它主要包括以下幾個方面[7]:
(1)數據表示。通信雙方進行通信時,將數據(調用方法參數等信息)串行化變成比特流的形式在內核中傳輸,到達接收方時,再還原成程序可識別的數據類型。數據表示是一種傳輸語法,用來表示數據類型串行化后以比特流表示出來的格式。GNOME的CORBA使用的格式為CDR;DCOP在上層使用QT的QDataStream工具類和C++流操作符將數據進行串行化,映射到低層ICE統一的數據類型;DBUS也規定基本的數據類型,并提供其他開發語言如GTK,QT,Python等到DBUS基本類型的映射。
(2)消息格式。由消息頭和消息體組成。一般情況下,消息頭包含消息的控制和說明信息,消息體包含具體的數據信息。高層協議帶有一定的語義信息,因此一般高層協議均對消息進行分類,定義了不同類型的消息格式。CORBA的互操作協議GIOP定義了CORBA的八種消息格式,典型的GIOP消息由三部分組成:GIOP消息頭、具體消息類型消息頭、具體消息類型消息體;DCOP映射到低層的ICE,ICE的消息由協議主操作符、協議次操作符、數據部分組成;DBUS的消息由消息頭和消息體組成,消息頭中定義消息類型、路由、調用對象、接口和方法或信號等控制信息,消息體由參數及其參數值組成。
(3)向低層協議的映射。高層協議是對高層消息格式的約定,并不能直接用來傳輸,因此必須向低層的協議進行映射以便被傳輸層所接受。CORBA的GIOP可以向TCP/IP映射,即為低層的IIOP協議;DCOP映射到ICE協議,然后ICE再映射到套接字上;DBUS也可以向套接字進行映射。此外進程通信協議還包括引用表示和連接管理等。
接口是一組相關操作的集合,定義了由服務器提供的、客戶可見的那些函數和特征,如函數名字、函數參數、參數屬性等。接口可以用現有的語言或獨立于具體編程語言的IDL來描述。接口經過特定的工具編譯后產生客戶存根和服務框架。CORBA的接口由與語言無關的CORBA IDL定義;DCOP的接口由C++語言和一些特定的預處理符號來定義;DBUS的接口目前由具體所綁定的語言所定義,一種獨立于編程語言的IDL——DBUS CIDL正在開發中,不過現在還沒有納入到DBUS的規范中。
通信查找方式主要指通信雙方如何找到對方。GNOME的CORBA實現ORBit主要通過命名服務來查找服務對象;DCOP通過桌面程序向DCOP服務器注冊的應用程序名和接口來定位所要調用的服務;DBUS為客戶端連接和服務器監聽的地址、消息總線、連接、對象、接口等指定一套命名規范,通過對象路徑來指定消息的源和目的地址。
7 結束語
目前桌面通信機制可以采用三種途徑來實現:
(1)在現有互操作體系的基礎上,根據桌面環境的特點,除去那些用于遠程通信的復雜協議和負載,以實現一個高效、輕量的桌面進程通信機制,如GNOME的CORBA實現。
(2)根據桌面環境的具體特點,“量身訂做”一個與桌面環境緊密結合,與語言有關的、高效的、輕量的、新的通信協議,如KDE的DCOP。
(3)獨立的、不依賴于具體桌面環境和語言的通信協議。通過與具體開發環境和語言的綁定整合到具體桌面環境
中,如DBUS。三種實現方式各有優缺點,用戶可以根據具體的需求來進行選擇。
參考文獻:
[1]李宋琛. Linux面向對象窗口高級編程[M].北京:科學出版社,2001.353-356.
[2]陳莉君.深入分析Linux內核源代碼[M].北京:人民郵電出版社,2002.263-285.
[3]Georg Wittenburg. Desktop IPC[EB/OL].http://page.mi.fuberlin.de/~wittenbu/uni/desktop_ipc.pdf, 2005.
[4]Diego Sevilla Ruiz, Mathieu Lacage, DirkJan C Binnema. GNOME CORBA[EB/OL]. http://developer.gnome.org/doc/guides/corba/html/book1.html, 2005.
[5]David Faure,et al. KDE Kontact: An Application Integration Framework PIM Components Get Together[EB/OL]. http://www.kontact.org/files/kontact_freenix_paper.pdf, 2005.
[6]Havoc Pennington. DBUS Specification[EB/OL].http://dbus.freedesktop.org/doc/.dbusspecification.html, 2005.
[7]王千祥.應用服務器原理與實現[M].北京:電子工業出版社,2003.47-56.
作者簡介:
陳華清,碩士研究生,主要研究方向為開放系統和中文信息處理;吳鍵,副研究員,主要研究方向為開放系統和中文信息處理。
注:本文中所涉及到的圖表、注解、公式等內容請以PDF格式閱讀原文