進程以及進程通訊(IPC)類型

這裏用我有限的知識來解釋同時參考了一些其餘博主的子類,但願能給與一部分入門的朋友一個清晰的理解,有問題之處還請指出linux

 

首先簡單談一下什麼是進程程序員

答:進程是裝入內存運行的程序段,是許多的系統對象擁有權的集合,換句你們常常引用的話說進程是資源分配的基本單位編程

舉例來講,咱們的瀏覽器程序存放在C盤的某個位置,這時它只是硬盤上的程序。每次咱們打開一個瀏覽器的時候,這個程序就會被裝入內存中去,進行一系列初始化(進程控制塊PCB的初始化,包括進程計數器,進程狀態,CPU命令,寄存器等等)。此時咱們看到了瀏覽器打開並顯示網頁,此時這就是一個運行中的進程,咱們能夠打開任務管理器看到許許多多運行的進程。windows


爲何說進程擁有許多系統對象?瀏覽器

答:剛纔說了,進程是裝入內存的程序段,那進程的運行勢必涉及到內存的分配(包括堆棧,文本區,數據區等,這裏是參考了C語言程序的內存分配),而進程所佔用的內存中就可能會有文件句柄,DLL模塊(在可執行程序運行時才載入內存的代碼),上下文等。安全

這裏,咱們順便說一下線程,你們記住線程是CPU運行調度的基本單位,線程必須被包含在進程中,一個進程能夠有不少線程(至少有一個),這些線程共享進程的許多資源(如棧,寄存器)。(關於進程與線程的優缺點,多線程的東西會在以後的博客裏寫)。服務器

 

什麼是進程通訊?爲何要通訊?網絡

答:進程通訊(IPC),即Inter-ProcessCommunication,字面上理解就是進程之間的通訊多線程

這裏舉一個不一樣主機的進程通訊,比較容易理解。你電腦上打開一個網頁,就能看到各類文字圖片,這些圖片是哪裏來的?如何獲取的?咱們上面說打開的瀏覽器就是一個進程,那瀏覽器獲取別處的圖片資源就是一種通訊的方式來拿到想要的東西的。瀏覽器向服務器發送請求獲取資源就是一種靠套接字來進行的進程通訊,這種通訊經過一臺主機的應用層端口以及Socket下發到運輸層(TCP),再通過下面的網絡層,數據鏈路層,物理層(這是計算機網絡5層模型)傳輸到另外一臺機器的socket,最後服務器獲取到該信息,實現進程間通訊。一句話說,A主機的瀏覽器經過socket與另外一臺B主機的進程進行通訊交流。app

 

 

進程屬於內核的基本功能,因此不一樣的操做系統在實現進程通訊有必定的區別,不過想通之處也仍是不少的。

其實,可能有不少同窗和朋友和我一開始理解的同樣,認爲IPC只有消息傳遞和共享內存兩種(沒錯,操做系統書上就是這麼寫的),可後來我發現消息傳遞具體是什麼,有什麼特色,我都說不太清~因此稍微研究了下

咱們能夠這樣理解:

IPC只是按形式上能夠分爲消息傳遞,共享內存,同步。

(下面是用linux的IPC舉例)

消息傳遞就包括,管道,FIFO命名管道,消息隊列

共享內存,包括匿名與具名的,

同步,包括互斥量,讀寫鎖,信號量等。

咱們能夠把每一種IPC都拿出來單獨做比較。

 

首先先大體說一下共享內存,管道的概念

其原理就是將一份物理內存映射到不一樣進程各自的虛擬地址空間,使每個進程均可以讀取這份數據,來實現通訊,由於是直接經過內存操做,因此是一種很是高效的通訊方式。

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

 

下面簡單介紹一下Windows與Linux的進程通訊以及比較:(這裏主要參考了 coolmeme 的博客)

Windows:

1.    文件映射

文件映射(Memory-Mapped Files)能使進程把文件內容看成進程地址區間一塊內存那樣來對待。所以,進程沒必要使用文件I/O操做(正常來講須要用輸入輸出流來讀寫文件ioStream),只需簡單的指針操做就可讀取和修改文件的內容。

Win32API容許多個進程訪問同一文件映射對象,各個進程在它本身的地址空間裏接收內存的指針。經過使用這些指針,不一樣進程就能夠讀或修改文件的內容,實現了對文件中數據的共享。

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

2.     共享內存 

Win32API中共享內存(SharedMemory)實際就是文件映射的一種特殊狀況。進程在建立文件映射對象時用0xFFFFFFFF來代替文件句柄(HANDLE),就表示了對應的文件映射對象是從操做系統頁面文件訪問內存,其它進程打開該文件映射對象就能夠訪問該內存塊。

3.    匿名管道

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

4.    命名管道

FIFO,先進先出的通訊方式。

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

5.    動態連接庫

DLL解釋:與動態連接庫鏈接的可執行文件只包含它須要的函數的引用表,而不是全部的函數代碼,只有在程序執行時, 那些須要的函數代碼才被拷貝到內存中這樣就使可執行文件比較小, 節省磁盤空間,操做系統使用虛擬內存,使得一份DLL駐留在內存中被多個程序使用,節省內存;

 Win32動態鏈接庫(DLL)中的全局數據能夠被調用DLL的全部進程共享,這就又給進程間通訊開闢了一條新的途徑,固然訪問時要注意同步問題。

6.    遠程調用RPC

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

7.    Socket

剛纔咱們舉例子簡單說明了socket(套接字)的做用,咱們要知道目前socket是一種很是流行的網絡通訊手段。

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

8.    剪貼板

Windows剪貼板應該算是一種比較簡單開銷小的IPC,內置在windows並使用系統的內部資源RAM,或者虛擬內存類臨時保存剪切和複製的信息,系統預留的一塊全局共享內存,用來暫存在各進程間進行交換的數據:提供數據的進程建立一個全局內存塊,並將要傳送的數據移到或複製到該內存塊;接受數據的進程(也能夠是提供數據的進程自己)獲取此內存塊的句柄,並完成對該內存塊數據的讀取。這裏有一點疑問,我認爲剪貼板並非把全部的信息複製到那個內存,而是把路徑等信息存入再進行拷貝(這裏但願有大神給解釋一下。。。)

9.    WM_COPYDATA消息

當一個應用向另外一個應用傳送數據時,發送方只需使用調用SendMessage函數,參數是目的窗口的句柄、傳遞數據的起始地址、WM_COPYDATA消息。接收方只需像處理其它消息那樣處理WM_COPY DATA消息,這樣收發雙方就實現了數據共享。WM_COPYDATA消息無疑是一種經濟實惠的一中方法

 

Linux:

1.    管道:

與上述windows的管道相似,也分爲匿名與有名字的管道。管道可用於具備親緣關係進程間(父子,兄弟進程)的通訊,有名管道克服了管道沒有名字的限制,容許不一樣無親緣關係的進程通訊。

2.    信號(signal):

信號是比較複雜的通訊方式,用於通知接受進程有某種事件發生,除了用於進程間通訊外,進程還能夠發送信號給進程自己;linux除了支持Unix早期信號語義函數sigal外,還支持語義符合Posix.1標準的信號函數sigaction

3.    報文(Message)隊列(消息隊列):

消息隊列是消息的連接表,包括Posix消息隊列system V消息隊列。有足夠權限的進程能夠向隊列中添加消息,被賦予讀權限的進程則能夠讀走隊列中的消息,注意消息隊列是建立文件方式創建,因此即便添加消息的進程結束,保存在消息隊列的消息也不會消失。

消息隊列克服了信號承載信息量少,管道只能承載無格式字節流以及緩衝區大小受限等缺點。

4.    共享內存:

上面描述了基本原理,每每與其它通訊機制,如信號量結合使用,來達到進程間的同步及互斥。

5.    信號量(semaphore):

主要做爲進程間以及同一進程不一樣線程之間的同步手段。(線程間通訊業常用信號量)

信號量是一個特殊的變量,只能對其進行初始化,PV以及刪除操做(這裏涉及到同步與鎖的一些內容,能夠查一下)。

6.    套接字(Socket):

上面描述過,可用於不一樣機器之間的進程間通訊。

 

 

 

對幾種IPC的簡單比較

1.    管道,速度較慢,緩衝區大小受限,只能承載無格式的字節流。只能用於有親緣關係的進程。

2.    FIFO管道,任何進程間均可以通訊,包括不一樣機器上的管道,速度較慢。

3.    消息隊列:由於位於內核中,因此容量受限,第一次讀取時要注意上次添加的消息是否讀取。

4.    信號量:不能傳遞複雜的消息,只用於同步信息。

5.    共享內存:能很容易的控制變量,速度快,要注意讀寫安全性,避免死鎖等。

上面的每一種通訊機制都有很大的研究價值,若是你們想詳細瞭解,還須要進一步去研究。
相關文章
相關標籤/搜索