這部分參考文獻2:詳細內容打開連接看html
程序員必須讓擁有依賴關係的進程集協調,這樣才能達到進程的共同目標。可使用兩種技術來達到協調。第一種技術在具備通訊依賴關係的兩個進程間傳遞信息。這種技術稱作進程間通訊(interprocess communication)。第二種技術是同步,當進程間相互具備合做依賴時使用。這兩種類型的依賴關係能夠同時存在。linux
通常而言,進程有單獨的地址空間。咱們能夠了解下可執行程序被裝載到內存後創建的一系列映射等理解這一點。如此以來意味着若是咱們有兩個進程(進程A和進程B),那麼,在進程A中聲明的數據對於進程B是不可用的。並且,進程B看不到進程A中發生的事件,反之亦然。若是進程A和B一塊兒工做來完成某個任務,必須有一個在兩個進程間通訊信息和時間的方法。咱們這裏能夠去看看基本的進程組件。注意進程有一個文本、數據以及堆棧片段。進程可能也有從自由存儲空間中分配的其它內存。進程所佔有的數據通常位於數據片段、堆棧片段或進程的動態分配內存中。數據對於其它進程來講是受保護的。爲了讓一個進程訪問另一個進程的數據,必須最終使用操做系統調用。與之相似,爲了讓一個進程知道另外一個進程中文本片段中發生的事件,必須在進程間創建一種通訊方式。這也須要來自操做系統API的幫助。當進程將數據發送到另外一進程時,稱作IPC(interprocess communication,進程間通訊)。程序員
下面先列舉幾種不一樣類型的進程間通訊方式:服務器
進程間通訊 | 描述 |
環境變量/文件描述符 | 子進程接受父進程環境數據的拷貝以及全部文件描述符。父進程能夠在它的數據片段或環境中設置必定的變量,同時子進程接收這些值。父進程能夠打開文件,同時推動讀/寫指針的位置,並且子進程使用相同的偏移訪問該文件。 |
命令行參數 | 在調用exec或派生函數期間,命令行參數能夠傳遞給子進程。 |
管道 | 用於相關和無關進程間的通訊,並且造成兩個進程間的一個通訊通道,一般使用文件讀寫程序訪問。 |
共享內存(動態數據交換,Dynamic data exchange)網絡 |
使用客戶機/服務器模型(C/S),服務器對客戶的數據 或動做請求做出反應。session |
DDE | 兩個進程以外的內存塊,兩個進程都可以訪問它。 |
1、環境變量、文件描述符:數據結構
當建立一個子進程時,它接受了父進程許多資源的拷貝。子進程接受了父進程的文本、堆棧app
以及數據片段的拷貝。子進程也接受了父進程的環境數據以及全部文件描述符的拷貝。子進socket
程從父進程繼承資源的過程創造了進程間通訊的一個機會。父進程能夠在它的數據片段或環函數
境中設置必定的變量,子進程因而接受這些值。一樣,父進程也能夠打開一個文件,推動到
文件內的指望位置,子進程接着就能夠在父進程離開讀/寫指針的準確位置訪問該文件。
這類通訊的缺陷在於它是單向的、一次性的通訊。也就是說,除了文件描述外,若是子進程
繼承了任何其它數據,也僅僅是父進程拷貝的全部數據。 一旦建立了子進程,由子進程對
這些變量的任何改變都不會反映到父進程的數據中。一樣,建立子進程後,對父進程數據的
任何改變也不會反映到子進程中。因此,這種類型的進程間通訊更像指揮棒傳遞。一旦父進
程傳遞了某些資源的拷貝,子進程對它的使用就是獨立的,必須使用原始傳遞資源。
2、命令行參數:
經過命令行參數(command-line argument)能夠完成另外一種單向、一次性的進程間通訊
我前面的文章已經提到過使用命令行參數。命令行參數在調用一個exec或派生調用操做系
統時傳遞給子進程。命令行參數一般在其中一個參數中做爲NULL終止字符串傳遞給exec
或派生函數調用。這些函數能夠按單向、一次性方式給子進程傳遞值。WINDOWS有調用執行
exe程序的API。你們能夠去參考一下ShellExecuteA函數相關。
3、管道通訊:
繼承資源以及命令行參數是最簡單形式的進程間通訊。它們同時有兩個主要限制。除了文件
描述符外,繼承資源是IPC的單向、一次性形式。傳遞命令參數也是單向、一次性的IPC
方法。這些方法也只有限制於關聯進程,若是不關聯,命令行參數和繼承資源不能使用。還
有另外一種結構,稱作管道(Pipe),它能夠用於在關聯進程間以及無關聯進程間進行通訊。
管道是一種數據結構,像一個序列化文件同樣訪問。它造成了兩個進程間的一種通訊渠道。
管道結構經過使用文本和寫方式來訪問。若是進程A但願經過管道發送數據給進程B,那麼
進程A向管道寫入數據。爲了讓進程B接收此數據,進程B必須讀取管道,與命令行參數的
IPC形式不同。管道能夠雙向通訊。兩進程間的數據流是雙向通訊的。管道能夠在程序的
整個執行期間使用,在進程間發送和接收數據。因此,管道充當可訪問管道的進程間的一種
可活連接,有兩種基本管道類型:
1. 匿名管道
2. 命名管道
上面的圖能夠看出在沒有管道時,兩進程是不能互寫的。
創建管道後就能夠相互通訊了。
4、 共享內存
共享內存也能夠實現進程間的通訊。進程須要能夠被其餘進程瀏覽的內存塊。但願訪問這個內存塊的其餘進程請求對它的訪問,或由建立它的進程授予訪問內存塊的權限。能夠訪問特定內存塊的全部進程對它具備即時可見性。共享內存被映射到使用它的每一個進程的地址空間。因此,它看起來像是另外一個在進程內聲明的變量。當一個進程寫共享內存,全部的進程都當即知道寫入的內容,並且能夠訪問。
進程間共享內存的關係與函數間全局變量的關係類似。程序中的全部函數均可以使用全局變量的值。一樣,共享內存塊能夠被正在執行的全部進程訪問。內存塊可能共享一個邏輯地址,進程也能夠共享某些物理地址。
共享內存塊的建立必須由一個系統API調用來完成。在WIN32環境中,使用CreateFileMapping()、MapViewOfFile()以及MapViewOfFileEx() API能很好地完成。
共享內存分配位於WIN32系統中2~3GB地址範圍內。一旦調用MapViewOfFile()和MapViewOfFileEx(),共享文件映射對象的全部進程均可以當即訪問此內存塊,並且在須要時,能夠讀寫此內存塊。
5、動態數據交換
動態數據交換( dynamic data exchange ) 是當今可用的進程間通訊最強大和完善的形式之一。動態數據交換使用消息傳遞、共享內存、事務協議、客戶/服務器範疇、同步規則以及會話協議來讓數據和控制信息在進程間流動。動態數據交換對話( dynamic data exchange session, DDE )的基本模型是客戶、服務器。服務器對來自客戶的數據或動做做出反應。客戶和服務器能夠以多種關係來通訊。
一個服務器能夠與任意數量的客戶通訊。一個客戶也能夠與任意數量的服務器通訊。單個DDE代理既能夠是客戶,也能夠是服務器。也就是說,進程能夠從一個正爲另外一個進程執行服務的DDE代理請求服務。
下部分參考文獻1:
進程間通訊主要包括管道, 系統IPC(包括消息隊列,信號量,共享存儲), SOCKET.
Windows系統進程間通訊
Windows提供了多種機制,使得應用程序之間可以快速、方便地共享數據和信息。這些機制包括RPC、COM、OLE、DDE、消息、剪切板、郵件槽、管道、套接字等。可是,若是在同一臺機器上的多個進程間進行通訊的話,那麼上面的機制都與共享內存有關。這在Windows上稱做內存映射文件。
這種數據共享機制是經過讓兩個或多個進程映射同一文件映射對象的視圖來實現,這意味着進程間共享相同的物理存儲頁面。所以,當一個進程在文件映射對象的視圖中寫入數據時,其餘的進程會在它們的視圖中馬上看到變化。可是,對多個進程共享同一個文件映射對象來講,全部進程使用的文件映射對象的名稱必須徹底相同[1]。
Linux系統進程間通訊
linux下的進程通訊手段基本上是從Unix平臺上的進程通訊手段繼承而來的。而對Unix發展作出重大貢獻的兩大主力AT&T的貝爾實驗室及BSD(加州大學伯克利分校的伯克利軟件發佈中心)在進程間通訊方面的側重點有所不一樣。前者對Unix早期的進程間通訊手段進行了系統的改進和擴充,造成了「system V IPC」,通訊進程侷限在單個計算機內;後者則跳過了該限制,造成了基於套接口(socket)的進程間通訊機制。Linux則把二者繼承了下來。
Linux下的進程間通訊機制大體包括:管道、信號(在Windows上成爲消息)、信號隊列(實際是消息鏈表)、共享內存、信號量、套接字。
共同點
由上面的分析能夠看出兩個操做系統共有的且用的較多的進程間通訊機制有:管道、消息、共享內存和套接字。簡介以下:
管道(Pipe)及有名管道(named pipe):管道可用於具備親緣關係進程間的通訊,有名管道克服了管道沒有名字的限制,所以,除具備管道所具備的功能外,它還容許無親緣關係進程間的通訊。
信號或者消息(Signal):信號是比較複雜的通訊方式,用於通知接受進程有某種事件發生,除了用於進程間通訊外,進程還能夠發送信號給進程自己。
共享內存:使得多個進程能夠訪問同一塊內存空間,是最快的可用IPC形式。是針對其餘通訊機制運行效率較低而設計的。每每與其它通訊機制,如信號量結合使用,來達到進程間的同步及互斥。
套接口(Socket):更爲通常的進程間通訊機制,可用於不一樣機器之間的進程間通訊。
總結
消息隊列是消息的連接表,消息隊列克服了信號承載信息量少,管道只能承載無格式字節流以及緩衝區大小受限等缺點;而信號量主要做爲進程間以及同一進程不一樣線程之間的同步手段。
我的認爲:管道、剪貼板、共享內存都是基於共享內存的方式。而消息、消息隊列和套接字的都是基於發消息的機制,只是看是在同一個機器上發仍是在網絡中發消息而已(套接字能夠看作在網絡中發送消息)。至於RPC、COM、OLE、DDE主要是在客戶端和服務器端生成一個統一的接口。也就是說這幾個通訊手段其實就至關於網絡上的協議。在同一層通訊的協議無論下一層,好像這兩層直接創建了聯繫。這個基本的思想是在本地創建相似存根代碼的代碼,而在遠程創建相似樁代碼的代碼來進行鏈接。
這上面的通訊方式中,剪切板和匿名管道只能實現同一機器上兩個進程間的通訊,而信號量、消息、消息隊列和共享內存也只能在同一臺機器上的多個進程間通訊;可是命名管道、郵件槽和套接字不只能夠實現同一機器上的兩個進程的通訊,還能夠實現跨網絡的進程間通訊;另外,油槽和套接字能夠實現一對多的通訊,而命名管道只能是點對點的單一通訊,但油槽的缺點是數據量較小,一般都是在424字節如下,若是數據量較大,則能夠採用命名管道和套接字的方式來完成。綜上:在跨網絡通訊中套接字無疑是最優秀的通訊方式,這或許是伯克利開發套接字來進行網絡通訊的初衷吧(傳統通訊方式很差用)。
參考:
1:http://blog.sina.com.cn/s/blog_6002b97001013wec.html
2:http://blog.csdn.net/liuzhanchen1987/article/details/7452910