引言:系統中進程間的通信及數據交換對于許多應用是至關重要的,尤其是隨著軟件開發模式逐漸走向分散化和模塊化的今天,系統內部或通信雙方各進程間協調、控制愈發頻繁起來,保持及時的通信及數據交換是完成好任務的必要條件。因此解決好此類問題是做好系統的全題條件。
1.進程及通信類型
1.1系統中進程的劃分
系統中的進程是裝入內存并準備執行的程序,每個進程都有私有的虛擬地址空間,由代碼、數據以及它可利用的系統資源(如文件、管道等)組成。對Windows操作系統而言,多用戶多任務是其最基本的要求,從而多進程是其基本特征。進程間共同完成特定任務時分工、協作是必然的,從此角度出發,可將系統中的進程分為兩類:客戶方進程和服務方進程[1]。客戶方進程是指發起通信的進程或應用程序,而服務方進程是指接受并應答發起方信號的進程。此種分類對所有的通信雙方都適用,但無益于軟件開發。另一種分類方法是從軟件開發的角度出發,可將系統中的進程分成已方進程、系統進程和他方進程[2]。已方進程即由軟件開發方開發的應用程序進入系統后形成的進程,而軟件開發方開發的應用程序以外的應用程序進入系統后形成的進程稱為他方進程,而系統進程則是由Windows操作系統所提供的進程。第三種分類方法是以進程所處的位置為出發點,可分為本地進程和遠程進程[3]。
1.2進程間的通信類型及特點
根據進程分類結果,可以得到進程間的通信類型:
Ⅰ、本地已方進程之間的通信;
Ⅱ、本地已方進程和遠程已方進程間的通信;
Ⅲ、本地已方進程和本地他方進程間的通信;
Ⅳ、本地已方進程和遠程他方進程間的通信;
對于第一種進程間通信,通信雙方進程的彼此都來自于同一軟件開發方,進程間通信的協議、數據和內容都可由軟件開發方在軟件設計階段統一加以考慮。軟件開發方在軟件設計階段充分考慮到進程間通信的需求,進而主動采取某種較為成熟的通信實現方式來分別設計實現進程間通信的客戶端和服務器端,從而形式進程間通信的既成的“默契”,這種“默契”實際上是在軟件設計階段就取得了,在此將這種通信模式稱為“有意識”型。
第二種進程間的通信方式,盡享了第一種進程間通信方式的便利,但不在開發時選擇通信的方式上受到了一定的限制,是一種有約束的“有意識”型模式。
第三種和第四種進程間的通信方式中,通信雙方來自完全不同的軟件開發方,由此很難在事先達成類似第一、二類型進程間的通信的那種“默契”,通信過程中,通信雙方往往沒有既定的客戶端和服務器端,服務器端完全不知道客戶端進程的存在,也不清楚客戶端要與之實現通信所使用的某種特定的協議的內容,服務端只能對符合自己格式和類型的客戶請求作出響應,故此這種通信模式是“無意識”型[2]的,不管進程是否在本地,通信的雙方都只是按自己認定的規則做事,在本地按既定的規則做,不在同一主機也按符合遠程通信的既定規則工作。
上述的分類方式有助于開發者選擇不同的通信方式,但不足以反映通信時進程的特點。因此,關于進程間的通信又常根據進程通信時信息量大小的不同分類,進程間傳遞少量的控制信息將其通信稱為低級通信,而傳遞大批數據信息時,將其稱為高級通信。
低級通信主要用于進程之間的同步、互斥、終止、掛起等等控制信息的傳遞。高級通信主要用于進程間數據塊的交換和共享。
2進程間通信方式及不同通信類別下的選用
2.1進程間通信方式及特點
Ⅰ、文件映射。文件映射(Memory-Mapped Files)能使進程把文件內容當作進程地址區間一塊內存那樣來對待。因此,進程不必使用文件I/O操作,只需簡單的指針操作就可讀取和修改文件的內容。但文件映射只能用于本地機器的進程之間,不能用于網絡中,而開發者還必須控制進程間的同步。
Ⅱ、共享內存。Win32 API中共享內存(Shared Memory)實際就是文件映射的一種特殊情況。進程在創建文件映射對象時用特定的地址來代替文件句柄(HANDLE),就表示了對應的文件映射對象是從操作系統頁面文件訪問內存,其它進程打開該文件映射對象就可以訪問該內存塊。由于共享內存是 用文件映射實現的,所以它也有較好的安全性,也只能運行于同一計算機上的進程之間。
Ⅲ、WM_COPYDATA消息。WM_COPYDATA是一種很好的數據傳輸方式。當一個應用向另一個應用傳送數據時,發送方只需使用調用SendMessage函數,參數是目的窗口的句柄、傳遞數據的起始地址、WM_COPYDATA消息。接收方只需像處理其它消息那樣處理WM_COPY DATA消息,這樣收發雙方就實現了數據共享。它的使用非常簡單,在底層實際上是通過文件映射來實現的。它的缺點是靈活性不高,并且它只能用于Windows平臺的單機環境下。
Ⅳ、剪貼板。剪貼板(Clipped Board)實質是Win32 API中一組用來傳輸數據的函數和消息,為Windows 應用程序之間進行數據共享提供了一個中介,Windows已建立的剪切(復制)-粘貼的機制為不同應用程序之間共享不同格式數據提供了一條捷徑。但剪貼板只能在基于Windows的程序中使用,不能在網絡上使用。
Ⅴ、動態數據交換。動態數據交換(DDE)是使用共享內存在應用程序之間進行數據交換的一種進程間通信形式。DDE交換可以發生在單機或網絡中不同計算機的應用程序之間。開發者還可以定義定制的DDE數據格式進行應用程序之間特別目的IPC,它們有更緊密耦合的通信要求。大多數基于Windows的應用程序都支持DDE。
Ⅵ、對象連接與嵌入。應用程序利用對象連接與嵌入(OLE)技術管理復合文檔(由多種數據格式組成的文檔),OLE提供使某應用程序更容易調用其它應用程序進行數據編輯的 服務。例如,OLE支持的字處理器可以嵌套電子表格,當用戶要編輯電子表格時OLE庫可自動啟動電子表格編輯器。當用戶退出電子表格編輯器時,該表格已在原始字處理器文檔中得到更新。在這里電子表格編輯器變成了字處理器的擴展,而如果使用DDE,用戶要顯式地啟動電子表格編輯器。同DDE技術相同,大多數基于Windows的應用程序都支持OLE技術。
Ⅶ、管道。管道(Pipe)是一種具有兩個端點的通信通道:有一端句柄的進程可以和有另一端句柄的進程通信。管道可以是單向即一端是只讀的,另一端點是只寫的;也可以是雙向的一管道的兩端點既可讀也可寫。
管道有兩種,一種是匿名管道(Anonymous Pipe),它用于在父進程和子進程之間,或同一父進程的兩個子進程之間傳輸數據的無名字的單向管道。匿名管道是單機上實現子進程標準I/O重定向的有效方法,它不能在網上使用,也不能用于兩個不相關的進程之間。另一種管道是命名管道,命名管道(Named Pipe)是服務器進程和一個或多個客戶進程之間通信的單向或雙向管道。命名管道提供了相對簡單的編程接口,使通過網絡傳輸數據并不比同一計算機上兩進程之間通信更困難,不過如果要同時和多個進程通信它就力不從心了。
Ⅷ、郵件槽。郵件槽(Mailslots)提供進程間單向通信能力,任何進程都能建立郵件槽成為郵件槽服務器。其它進程,稱為郵件槽客戶,可以通過郵件槽的名字給郵件槽服務器進程發送消息。進來的消息一直放在郵件槽中,直到服務器進程讀取它為止。一個進程既可以是郵件槽服務器也可以是郵件槽客戶,因此可建立多個郵件槽實現進程間的雙向通信。
Ⅸ、動態連接庫。Win32動態連接庫(DLL)中的全局數據可以被調用DLL的所有進程共享,這就又給進程間通信開辟了一條新的途徑,當然訪問時要注意同步問題。雖然可以通過DLL進行進程間數據共享,但從數據安全的角度考慮,我們并不提倡這種方法,使用帶有訪問權限控制的共享內存的方法更好一些。
Ⅹ、遠程過程調用。Win32 API提供的遠程過程調用(RPC)使應用程序可以使用遠程調用函數,這使在網絡上用RPC進行進程通信就像函數調用那樣簡單。RPC既可以在單機不同進程間使用也可以在網絡中使用。由于Win32 API提供的RPC服從OSF-DCE (Open Software Foundation Distributed Computing Environment)標準。所以通過 Win32 API編寫的RPC應用程序能與其它操作系統上支持DEC的RPC應用程序通信。使用RPC開發者可以建立高性能、緊密耦合的分布式應用程序。
Ⅺ、NetBios函數[4]。Win32 API提供NetBios函數用于處理低級網絡控制,這主要是為IBM NetBios系統編寫與Windows的接口。除非那些有特殊低級網絡功能要求的應用程序,其它應用程序最好不要使用NetBios函數來進行進程間通信。
Ⅻ、Windows套接字(Windows Sockets)。Windows套接字規范是以U.C.Berkeley大學BSD UNIX中流行的Socket接口為范例定義的一套Windows下的網絡編程接口,是跨平臺的協議,現在通過Sockets實現進程通信的網絡應用越來越多。另外高版本的 WinSock 不僅支持TCP/IP協議,而且還支持其它協議(如IPX)。Sockets的唯一缺點是它支持的是底層通信操作,使用是十分繁瑣,這使得在本地進程間進行簡單數據傳遞較為不便。
2.2 第一種通信進程類型間通信的實現方法
所有的通信,對于通信的雙方均需要事先達成通信協議方可實現,對于第一種通信類型的進程間的通信,通信的雙方是同一開發者,取得“默契”條件成熟,實現較易。較其方式也最多。主要有以下幾種: 文件映射、共享內存、WM_COPYDATA消息、剪貼板、動態數據交換、對象連接與嵌入、匿名管道、動態連接庫、NetBios函數、Windows套接字等。
2.3第二種通信進程類型間通信的實現方法
雖然與第一種一樣有取得“默契”的先天條件,但由于通信的雙方處于不同的主機中,且由于Windows操作系統的進程間的保護機制,會造成執行時發生數據存取的保護性錯誤(Access Voilaton),故通信的方式受到一定的限制。此種有意識模型的通信方式主要有以下幾種:文件映射、WM_COPYDATA消息、動態數據交換、對象連接與嵌入、命名管道、郵件槽、Windows套接字(Windows Sockets)等。
2.3第三種通信進程類型間通信的實現方法
本種通信進程類型中的通信雙方雖然處于同一主機中,但由于開發者的不同,雙方只能根據公共的規則和協議實現各自的開發。故其通信方式亦受到一定的約束,其常用的方式有如下幾種:動態數據交換、對象連接與嵌入、命名管道、郵件槽、Windows套接字等。
2.4第四種通信進程類型間通信的實現方法
這種通信進程類型中的通信雙方間的通信所受的制約最多,既要考慮到進程間遠程特性,又要考慮到雙方的開發者“不識”,故其通信方式在選擇時最為謹慎,常用的通信方式有:命名管道、郵件槽、Windows套接字等。
3.結語
系統進程繁多,Wiondows32下為進程間提供的通信方式繁雜,在軟件開發的過程中,對不同類型進程間的通信方式選用適當的通信方式,既能適當減少開發的工作量又能保證所開發軟件的健壯性和可靠性,同時能大大提高了通信的靈活性。在實際開發中,將幾種模式的進程間通信的實現方法結合起來加以應用,即可實現各類進程間的數據交換。
參考文獻
[1]新編WINDOWS API參考大全編寫組.新編WINDOWSAPI參考大全[M].北京:電子工業出版社,2005.
[2]梁庚,白焰. Windows下進程間通信方式探討[J] 微型電腦應用 2006,(22):44,58~60.
[3]求是科技 王洪濤編著. 深入剖析Visual C++[M].北京:人民郵電出版社,2004.
[3]David Bennet著.徐軍譯.VC++5開發人員指南[M].北京:機械工業出版社,1998.
[4]肖紅偉.VC++6.0編程實效百例[M].北京:人民郵電出版社,2002.
(作者單位:無錫商業職業技術學院物聯網技術學院)