Linux與Windows進程間通信(IPC)--總結網絡中內容

原文地址:

http://www.cnblogs.com/raymon/archive/2012/02/18/2357608.html

http://blog.csdn.net/kesalin/article/details/3887368

 

1. Linux進程間通信方式

進程間通信就是在不同進程之間傳播或交換信息,那麼不同進程之間存在着什麼雙方都可以訪問的介質呢?進程的用戶空間是互相獨立的,一般而言是不能互相訪問的,唯一的例外是共享內存區。但是,系統空間卻是“公共場所”,所以內核顯然可以提供這樣的條件。除此以外,那就是雙方都可以訪問的外設了。在這個意義上,兩個進程當然也可以通過磁盤上的普通文件交換信息,或者通過“註冊表”或其它數據庫中的某些表項和記錄交換信息。廣義上這也是進程間通信的手段,但是一般都不把這算作“進程間通信”。因爲那些通信手段的效率太低了,而人們對進程間通信的要求是要有一定的實時性。

Linux下進程通信的八種方法:管道(pipe),命名管道(FIFO),內存映射(mappedmemeory),消息隊列(message queue),共享內存(shared memory),信號量(semaphore),信號(signal),套接字(Socket).

(1) 管道(pipe):管道允許一個進程和另一個與它有共同祖先的進程之間進行通信;

(2) 命名管道(FIFO):類似於管道,但是它可以用於任何兩個進程之間的通信,命名管道在文件系統中有對應的文件名。有名管道克服了管道沒有名字的限制,因此,除具有管道所具有的功能外,它還允許無親緣關係進程間的通信。命名管道通過命令mkfifo或系統調用mkfifo來創建;

管道包括三種:1)普通管道PIPE,通常有種限制,一是半雙工,只能單向傳輸;二是只能在父子進程間使用.2)流管道s_pipe:去除了第一種限制,可以雙向傳輸. 3)命名管道:name_pipe,去除了第二種限制,可以在許多並不相關的進程之間進行通訊.

(3) 信號(signal):信號是比較複雜的通信方式,用於通知接收進程有某種事情發生,除了用於進程間通信外,進程還可以發送信號給進程本身;Linux除了支持UNIX早期信號語義函數signal外,還支持語義符合POSIX.1標準的信號函數sigaction(實際上,該函數是基於BSD的,BSD即能實現可靠信號機制,又能夠統一對外接口,用sigaction函數重新實現了signal函數的功能);

(4) 內存映射(mapped memory):內存映射允許任何多個進程間通信,每一個使用該機制的進程通過把一個共享的文件映射到自己的進程地址空間來實現它;

(5) 消息隊列(message queue):消息隊列是消息的連接表,包括POSIX消息對和System V消息隊列。有足夠權限的進程可以向隊列中添加消息,被賦予讀權限的進程則可以讀走隊列中的消息。消息隊列克服了信號承載信息量少,管道只能成該無格式字節流以及緩衝區大小受限等缺點;

(6) 信號量(semaphore):信號量主要作爲進程間以及同進程不同線程之間的同步手段;

(7) 共享內存(shared memory):它使得多個進程可以訪問同一塊內存空間,是最快的可用IPC形式。這是針對其他通信機制運行效率較低而設計的。它往往與其他通信機制,如信號量結合使用,以達到進程間的同步及互斥;

(8) 套接字(Socket):它是更爲通用的進程間通信機制,可用於不同機器之間的進程間通信。起初是由UNIX系統的BSD分支開發出來的,但現在一般可以移植到其他類UNIX系統上:LinuxSystem V的變種都支持套接字;

2. Windows進程間通信方式

2.1 文件映射

文件映射(Memory-MappedFiles)能使進程把文件內容當作進程地址區間一塊內存那樣來對待。因此,進程不必使用文件I/O操作,只需簡單的指針操作就可讀取和修改文件的內容。

Win32 API允許多個進程訪問同一文件映射對象,各個進程在它自己的地址空間裏接收內存的指針。通過使用這些指針,不同進程就可以讀或修改文件的內容,實現了對文件中數據的共享。

應用程序有三種方法來使多個進程共享一個文件映射對象。

(1)繼承:第一個進程建立文件映射對象,它的子進程繼承該對象的句柄。

(2)命名文件映射:第一個進程在建立文件映射對象時可以給該對象指定一個名字(可與文件名不同)。第二個進程可通過這個名字打開此文件映射對象。另外,第一個進程也可以通過一些其它IPC機制(有名管道、郵件槽等)把名字傳給第二個進程。

(3)句柄複製:第一個進程建立文件映射對象,然後通過其它IPC機制(有名管道、郵件槽等)把對象句柄傳遞給第二個進程。第二個進程複製該句柄就取得對該文件映射對象的訪問權限。

文件映射是在多個進程間共享數據的非常有效方法,有較好的安全性。但文件映射只能用於本地機器的進程之間,不能用於網絡中,而開發者還必須控制進程間的同步。

2.2 共享內存

Win32 API中共享內存(SharedMemory)實際就是文件映射的一種特殊情況。進程在創建文件映射對象時用0xFFFFFFFF來代替文件句柄(HANDLE),就表示了對應的文件映射對象是從操作系統頁面文件訪問內存,其它進程打開該文件映射對象就可以訪問該內存塊。由於共享內存是用文件映射實現的,所以它也有較好的安全性,也只能運行於同一計算機上的進程之間。

2.3 匿名管道

管道(Pipe)是一種具有兩個端點的通信通道:有一端句柄的進程可以和有另一端句柄的進程通信。管道可以是單向-一端是隻讀的,另一端點是隻寫的;也可以是雙向的一管道的兩端點既可讀也可寫。

匿名管道(Anonymous Pipe)是在父進程和子進程之間,或同一父進程的兩個子進程之間傳輸數據的無名字的單向管道。通常由父進程創建管道,然後由要通信的子進程繼承通道的讀端點句柄或寫端點句柄,然後實現通信。父進程還可以建立兩個或更多個繼承匿名管道讀和寫句柄的子進程。這些子進程可以使用管道直接通信,不需要通過父進程。

匿名管道是單機上實現子進程標準I/O重定向的有效方法,它不能在網上使用,也不能用於兩個不相關的進程之間。

2.4 命名管道

命名管道(Named Pipe)是服務器進程和一個或多個客戶進程之間通信的單向或雙向管道。不同於匿名管道的是命名管道可以在不相關的進程之間和不同計算機之間使用,服務器建立命名管道時給它指定一個名字,任何進程都可以通過該名字打開管道的另一端,根據給定的權限和服務器進程通信。

命名管道提供了相對簡單的編程接口,使通過網絡傳輸數據並不比同一計算機上兩進程之間通信更困難,不過如果要同時和多個進程通信它就力不從心了。

2.5 郵件槽

郵件槽(Mailslots)提供進程間單向通信能力,任何進程都能建立郵件槽成爲郵件槽服務器。其它進程,稱爲郵件槽客戶,可以通過郵件槽的名字給郵件槽服務器進程發送消息。進來的消息一直放在郵件槽中,直到服務器進程讀取它爲止。一個進程既可以是郵件槽服務器也可以是郵件槽客戶,因此可建立多個郵件槽實現進程間的雙向通信。

通過郵件槽可以給本地計算機上的郵件槽、其它計算機上的郵件槽或指定網絡區域中所有計算機上有同樣名字的郵件槽發送消息。廣播通信的消息長度不能超過400字節,非廣播消息的長度則受郵件槽服務器指定的最大消息長度的限制。

郵件槽與命名管道相似,不過它傳輸數據是通過不可靠的數據報(TCP/IP協議中的UDP)完成的,一旦網絡發生錯誤則無法保證消息正確地接收,而命名管道傳輸數據則是建立在可靠連接基礎上的。不過郵件槽有簡化的編程接口和給指定網絡區域內的所有計算機廣播消息的能力,所以郵件槽不失爲應用程序發送和接收消息的另一種選擇。

2.6 剪貼板

剪貼板(Clipped Board)實質是Win32 API中一組用來傳輸數據的函數和消息,爲Windows應用程序之間進行數據共享提供了一箇中介,Windows已建立的剪切(複製)-粘貼的機制爲不同應用程序之間共享不同格式數據提供了一條捷徑。當用戶在應用程序中執行剪切或複製操作時,應用程序把選取的數據用一種或多種格式放在剪貼板上。然後任何其它應用程序都可以從剪貼板上拾取數據,從給定格式中選擇適合自己的格式。

剪貼板是一個非常鬆散的交換媒介,可以支持任何數據格式,每一格式由一無符號整數標識,對標準(預定義)剪貼板格式,該值是Win32 API定義的常量;對非標準格式可以使用Register Clipboard Format函數註冊爲新的剪貼板格式。利用剪貼板進行交換的數據只需在數據格式上一致或都可以轉化爲某種格式就行。但剪貼板只能在基於Windows的程序中使用,不能在網絡上使用。

2.7 動態數據交換

動態數據交換(DDE)是使用共享內存在應用程序之間進行數據交換的一種進程間通信形式。應用程序可以使用DDE進行一次性數據傳輸,也可以當出現新數據時,通過發送更新值在應用程序間動態交換數據。

DDE和剪貼板一樣既支持標準數據格式(如文本、位圖等),又可以支持自己定義的數據格式。但它們的數據傳輸機制卻不同,一個明顯區別是剪貼板操作幾乎總是用作對用戶指定操作的一次性應答-如從菜單中選擇Paste命令。儘管DDE也可以由用戶啓動,但它繼續發揮作用一般不必用戶進一步干預。DDE有三種數據交換方式:

(1) 冷鏈:數據交換是一次性數據傳輸,與剪貼板相同。

(2) 溫鏈:當數據交換時服務器通知客戶,然後客戶必須請求新的數據。

(3) 熱鏈:當數據交換時服務器自動給客戶發送數據。

DDE交換可以發生在單機或網絡中不同計算機的應用程序之間。開發者還可以定義定製的DDE數據格式進行應用程序之間特別目的IPC,它們有更緊密耦合的通信要求。大多數基於Windows的應用程序都支持DDE

2.8 對象連接與嵌入

應用程序利用對象連接與嵌入(OLE)技術管理複合文檔(由多種數據格式組成的文檔)OLE提供使某應用程序更容易調用其它應用程序進行數據編輯的服務。例如,OLE支持的字處理器可以嵌套電子表格,當用戶要編輯電子表格時OLE庫可自動啓動電子表格編輯器。當用戶退出電子表格編輯器時,該表格已在原始字處理器文檔中得到更新。在這裏電子表格編輯器變成了字處理器的擴展,而如果使用DDE,用戶要顯式地啓動電子表格編輯器。

DDE技術相同,大多數基於Windows的應用程序都支持OLE技術。

2.9 動態連接庫

Win32動態連接庫(DLL)中的全局數據可以被調用DLL的所有進程共享,這就又給進程間通信開闢了一條新的途徑,當然訪問時要注意同步問題。

雖然可以通過DLL進行進程間數據共享,但從數據安全的角度考慮,我們並不提倡這種方法,使用帶有訪問權限控制的共享內存的方法更好一些。

2.10 遠程過程調用

Win32 API提供的遠程過程調用(RPC)使應用程序可以使用遠程調用函數,這使在網絡上用RPC進行進程通信就像函數調用那樣簡單。RPC既可以在單機不同進程間使用也可以在網絡中使用。

由於Win32 API提供的RPC服從OSF-DCE(OpenSoftware Foundation Distributed Computing Environment)標準。所以通過Win32API編寫的RPC應用程序能與其它操作系統上支持DECRPC應用程序通信。使用RPC開發者可以建立高性能、緊密耦合的分佈式應用程序。

2.11 NetBios函數

Win32 API提供NetBios函數用於處理低級網絡控制,這主要是爲IBM NetBios系統編寫與Windows的接口。除非那些有特殊低級網絡功能要求的應用程序,其它應用程序最好不要使用NetBios函數來進行進程間通信。

2.12 Sockets

Windows Sockets規範是以U.C.Berkeley大學BSD UNIX中流行的Socket接口爲範例定義的一套Windows下的網絡編程接口。除了BerkeleySocket原有的庫函數以外,還擴展了一組針對Windows的函數,使程序員可以充分利用Windows的消息機制進行編程。

現在通過Sockets實現進程通信的網絡應用越來越多,這主要的原因是Sockets的跨平臺性要比其它IPC機制好得多,另外WinSock 2.0不僅支持TCP/IP協議,而且還支持其它協議(IPX)Sockets的唯一缺點是它支持的是底層通信操作,這使得在單機的進程間進行簡單數據傳遞不太方便,這時使用下面將介紹的WM_COPYDATA消息將更合適些。

2.13 WM_COPYDATA消息

WM_COPYDATA是一種非常強大卻鮮爲人知的消息。當一個應用向另一個應用傳送數據時,發送方只需使用調用SendMessage函數,參數是目的窗口的句柄、傳遞數據的起始地址、WM_COPYDATA消息。接收方只需像處理其它消息那樣處理WM_COPY DATA消息,這樣收發雙方就實現了數據共享。

WM_COPYDATA是一種非常簡單的方法,它在底層實際上是通過文件映射來實現的。它的缺點是靈活性不高,並且它只能用於Windows平臺的單機環境下。

3.相關問題

FAQ1: 管道與文件描述符,文件指針的關係?

: 其實管道的使用方法與文件類似,都能使用read,write,open等普通IO函數.管道描述符類似於文件描述符. 事實上,管道使用的描述符, 文件指針和文件描述符最終都會轉化成系統中SOCKET描述符.都受到系統內核中SOCKET描述符的限制.本質上LINUX內核源碼中管道是通過空文件來實現.

FAQ2: 管道的使用方法?

: 主要有下面幾種方法: 1)pipe,創建一個管道,返回2個管道描述符.通常用於父子進程之間通訊. 2)popen, pclose:這種方式只返回一個管道描述符,常用於通信另一方是stdin or stdout; 3)mkpipe:命名管道, 在許多進程之間進行交互.

FAQ3: 管道與系統IPC之間的優劣比較?

: 管道:優點是所有的UNIX實現都支持,並且在最後一個訪問管道的進程終止後,管道就被完全刪除;缺陷是管道只允許單向傳輸或者用於父子進程之間.

系統IPC: 優點是功能強大,能在毫不相關進程之間進行通訊;缺陷是關鍵字KEY_T使用了內核標識,佔用了內核資源,而且只能被顯式刪除,而且不能使用SOCKET的一些機制,例如select,epoll.

FAQ4: WINDOS進程間通信與LINUX進程間通信的關係?

: 事實上,WINDOS的進程通信大部分移植於UNIX, WINDOS的剪貼板,文件映射等都可從UNIX進程通信的共享存儲中找到影子.

FAQ5: 進程間通信與線程間通信之間的關係?

: 因爲WINDOWS運行的實體是線程,狹義上的進程間通信其實是指分屬於不同進程的線程之間的通訊.而單個進程之間的線程同步問題可歸併爲一種特殊的進程通信.它要用到內核支持的系統調用來保持線程之間同步.通常用到的一些線程同步方法包括:Event, Mutex, 信號量Semaphore,臨界區資源等.

發佈了41 篇原創文章 · 獲贊 8 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章