原因
為了提高計算機系統的效率.增強計算機系統內各種硬體的並行操作能力.作業系統要求程式結構必須適應並發處理的需要.為此引入了進程的概念。進程是作業系統的核心,所有基於多道程式設計的作業系統都建立在進程的概念之上。目前的計算機系統均提供了多任務並行環境.無論是應用程式還是系統程式.都需要針對每一個任務創建相應的進程。進程是設計和分析作業系統的有力工具。然而不同的進程之間.即使是具有家族聯繫的父子進程.都具有各自不同的進程映像。由於不同的進程運行在各自不同的記憶體空間中.一方對於變數的修改另一方是無法感知的.因此.進程之間的信息傳遞不可能通過變數或其它數據結構直接進行,只能通過進程間通信來完成。
並發進程之間的相互通信是實現多進程間協作和同步的常用工具.具有很強的實用性,進程通信是作業系統核心層極為重要的部分。
分類
根據交換信息量的多少和效率的高低,進程通信分為如下低級通信和高級通信。
低級通信
由於進程的互斥和同步,需要在進程間交換一定的信息,故不少學者將它們也歸為進程通信。只能傳遞狀態和整數值(控制信息)。
特點:傳送信息量小,效率低,每次通信傳遞的信息量固定,若傳遞較多信息則需要進行多次通信。
編程複雜:用戶直接實現通信的細節,容易出錯。
高級通信
提高信號通信的效率,傳遞大量數據,減輕程式編制的複雜度。
提供三種方式:
1.共享記憶體模式
2.訊息傳遞模式
3.已分享檔案模式
基本進程通訊方法
共享存儲(間接通信)
Shared-memory:相互通訊的進程有共享存儲區.進程間可以通過直接讀寫共享存儲區的變數來互動數據,同步與互斥在並發程式設計時安排進入程式。作業系統提供這樣的共享存儲區及同步互斥工具。
最為快捷有效的方式之一,UNIX系統中常被使用。記憶體共享區的互斥要通過其它機制實現;數據的傳送方不關心數據由誰接收,數據的接收方也不關心數據是由誰傳送的,存在安全隱患。
訊息傳遞
message-passing:通過作業系統的相應系統調用進行訊息傳遞通訊。分為直接和間接兩種:
直接通信方式:點到點的傳送
Send (DestProcessName, Message);
Receive (SourceProcessName, Message);
基本思想:進程在傳送和接收訊息時直接指明接收者或傳送者進程ID。
缺點:必須指定接收進程ID。(UNIX的信號機制類似這種形式)
間接通信方式:以信箱為媒介進行傳遞,可以廣播
Send (MailBox, Message);
Receive (MailBox, Message);
間接通信方式(信箱命名法)
基本思想:系統為每個信箱設一個訊息佇列,訊息傳送和接收都指向該訊息佇列。
缺點:必須有一個通訊雙方共享的一個邏輯訊息佇列( UNIX的PIPE,FIFO及IPC訊息傳遞機制都屬於這種形式),使用時訊息傳送者約定寫方式打開信箱,訊息接受者約定讀方式打開信箱或同時讀寫打開。
優點:很容易建立雙向通訊鏈(只要對信箱說明為讀寫打開)。
管道通信
是一種信息流緩衝機構, UNIX系統中管道基於檔案系統,在核心中通過檔案描述符表示。管道以先進先出(FIFO)方式組織數據傳輸。
實現方法:
調用pipe()函式創建管道
int pipe(int fd[2]);
fd[0]為管道里的讀取端
fd[1]則為管道的寫入端。
通過write()函式寫入信息
int write (int handle,char *buf,unsigned len)
進程通過read()函式讀取信息
int read (int handle,void *buf,unsigned len)
特點
1.管道是一個單向通信信道,如果進程間要進行雙向通信,通常需要定義兩個管道。
2.管道通過系統調用read(), write()函式進行讀寫操作。
分類
1.匿名管道:只適用於父子進程之間通信;管道能夠把信息從一個進程的地址空間拷貝到另一個進程的地址空間。
2.命名管道:命名管道有自己的名字和訪問許可權的限制,就像一個檔案一樣。它可以用於不相關進程間的通信,進程通過使用管道的名字獲得管道。
含義
兩個並行進程可以通過互相傳送訊息進行合作,訊息是通過訊息緩衝而在進程之間相互傳遞。
UNIX系統中的進程間的通訊有兩層含義:
---單一進程內部各個模組間的通訊
---作為單獨單位的各個不同進程間的通訊
前者沿襲了單任務作業系統中的模組通訊方法;
後者必須保證各個進程在通訊過程中互不干擾從而保持其通信的一致性。
方式
1) 檔案和記錄鎖定。
為避免兩個進程間同時要求訪問同一共享資源而引起訪問和操作的混亂,在進程對共享資源進行訪問前必須對其進行鎖定,該進程訪問完後再釋放。這是UNIX為共享資源提供的互斥性保障。
2)管道。
管道一般用於兩個不同進程之間的通信。當一個進程創建一個管道,並調用fork創建自己的一個子進程後,父進程關閉讀管道端,子進程關閉寫管道端,這樣 提供了兩個進程之間數據流動的一種方式。
3)FIFO。
FIFO是一種先進先出的佇列。它類似於一個管道,只允許數據的單向流動。每個FIFO都有一個名字,允許不相關的進程訪問同一個FIFO。因此也成為命名管。
4)訊息佇列。
UNIX下不同進程之間可實現共享資源的一種機制;UNIX允許不同進程將格式化的數據流以訊息形式傳送給任意進程。對訊息佇列具有操作許可權的進程都可以使用msget完成對訊息佇列的操作控制。通過使用訊息類型,進程可以按任何順序讀訊息,或為訊息安排優先權順序。
5)信號燈。
作為進程間通訊的一種方法,它不是用於交換大批數據,而用於多進程之間的同步(協調對共享存儲段的存取)。
6)共享記憶體。
通過信號燈實現存儲共享(類似“紅燈停、綠燈行”)
優缺點
幾種通信方法總結綜上所述.進程之間的多種通信方法各自有各自的優點和缺點:如果用戶傳遞的信息較少.或是需要通過信號來觸發某些行為.前文提到的軟中斷信號機制不失為一種簡捷有效的進程間通信方式.但若是進程間要求傳遞的信息量比較大或者進程間存在交換數據的要求,那就需要考慮別的通信方式了。無名管道簡單方便.但局限於單向通信的工作方式.並且只能在創建它的進程及其子孫進程之間實現管道的共享:有名管道雖然可以提供給任意關係的進程使用.但是由於其長期存在於系統之中,使用不當容易出錯,所以普通用戶一般不建議使用。訊息緩衝可以不再局限於父子進程.而允許任意進程通過共享訊息佇列來實現進程間通信.並由系統調用函式來實現訊息傳送和接收之間的同步.從而使得用戶在使用訊息緩衝進行通信時不再需要考慮同步問題.使用方便,但是信息的複製需要額外消耗CPU的時間.不適宜於信息量大或操作頻繁的場合。共享記憶體針對訊息緩衝的缺點改而利用記憶體緩衝區直接交換信息,無須複製,快捷、信息量大是其優點。但是共享記憶體的通信方式是通過將共享的記憶體緩衝區直接附加到進程的虛擬地址空間中來實現的。因此,這些進程之間的讀寫操作的同步問題作業系統無法實現。必須由各進程利用其他同步工具解決。另外,由於記憶體實體存在於計算機系統中.所以只能由處於同一個計算機系統中的諸進程共享。不方便網路通信。不同的進程通信方式有不同的優點和缺點.因此.對於不同的套用問題,要根據問題本身的情況來選擇進程間的通信方式。
一般來說,進程間的通信根據通信內容可以劃分為兩種:即控制信息的傳送與大批數據傳送。有時也把進程間控制信息的交換稱為低級通信,而把進程間大批量數據的交換稱為高級通信。