linux 程序間通訊的3種高階方式及優缺點

2022-09-16 04:30:15 字數 4143 閱讀 6161

由於不同的程序執行在各自不同的記憶體空間中.一方對於變數的修改另一方是無法感知的.因此.程序之間的資訊傳遞不可能通過變數或其它資料結構直接進行,只能通程序間通訊來完成。

根據程序通訊時資訊量大小的不同,可以將程序通訊劃分為兩大型別:控制資訊的通訊和大批資料資訊的通訊.前者稱為低階通訊,後者稱為高階通訊。

低階通訊主要用於程序之間的同步、互斥、終止、掛起等等控制資訊的傳遞。

高階通訊主要用於程序間資料塊的交換和共享 常見的高階通訊有管道(pipe)、訊息佇列(message)、共享記憶體(shared mem0ry)等。

這裡主要比較一下高階通訊的這三種方式的特點。

管道通訊(pipe)

兩個程序利用管道進行通訊時.傳送資訊的程序稱為寫程序.接收資訊的程序稱為讀程序。管道通訊方式的中間介質就是檔案.通常稱這種檔案為管道檔案.它就像管道一樣將乙個寫程序和乙個讀程序連線在一起,實現兩個程序之間的通訊。寫程序通過寫入端(傳送端)往管道檔案中寫入資訊;讀程序通過讀出端(接收端)從管道檔案中讀取資訊。兩個程序協調不斷地進行寫和讀,便會構成雙方通過管道傳遞資訊的流水線。

利用系統呼叫pipe()可以建立乙個無名管道檔案,通常稱為無名管道或pipe;利用系統呼叫mknod()可以建立乙個有名管道檔案.通常稱為有名管道或fifo。無名管道是一種非永

久性的管道通訊機構.當它訪問的程序全部終止時,它也將隨之被撤消。無名管道只能用在具有家族聯絡的程序之間。有名管道可以長期存在於系統之中.而且提供給任意關係的程序使用,但是使用不當容易導致出錯.所以作業系統將命名管道的管理權交由系統來加以控制管道檔案被建立後,可以通過系統呼叫write()和read()來實現對管道的讀寫操作;通訊完後,可用close()將管道檔案關閉。

訊息緩衝通訊(message)

多個獨立的程序之間可以通過訊息緩衝機制來相互通訊.這種通訊的實現是以訊息緩衝區為中間介質.通訊雙方的傳送和接收操作均以訊息為單位。在儲存器中,訊息緩衝區被組織成佇列,通常稱之為訊息佇列。訊息佇列一旦建立後即可由多程序共享.傳送訊息的程序可以在任意時刻傳送任意個訊息到指定的訊息佇列上,並檢查是否有接收程序在等待它所傳送的訊息。若有則喚醒它:而接收訊息的程序可以在需要訊息的時候到指定的訊息佇列上獲取訊息.如果訊息還沒有到來.則轉入睡眠狀態等待。

共享記憶體通訊(shared memory)

針對訊息緩衝需要占用cpu進行訊息複製的缺點.os提供了一種程序間直接進行資料交換的通訊方式一共享記憶體 顧名思義.這種通訊方式允許多個程序在外部通訊協議或同步,互斥機制的支援下使用同乙個記憶體段(作為中間介質)進行通訊.它是一種最有效的資料通訊方式,其特點是沒有中間環節.直接將共享的記憶體頁面通過附接.對映到相互通訊的程序各自的虛擬位址空間中.從而使多個程序可以直接訪問同乙個物理記憶體頁面.如同訪問自己的私有空間一樣(但實質上不是私有的而是共享的)。因此這種程序間通訊方式是在同乙個計算機系統中的諸程序間實現通訊的最快捷的方法.而它的侷限性也在於此.即共享記憶體的諸程序必須共處同乙個計算機系統.有物理記憶體可以共享才行。

三種方式的特點(優缺點):

1.無名管道簡單方便.但侷限於單向通訊的工作方式.並且只能在建立它的程序及其子孫程序之間實現管道的共享:有名管道雖然可以提供給任意關係的程序使用.但是由於其長期存在於系統之中,使用不當容易出錯。

2.訊息緩衝可以不再侷限於父子程序.而允許任意程序通過共享訊息佇列來實現程序間通訊.並由系統呼叫函式來實現訊息傳送和接收之間的同步.從而使得使用者在使用訊息緩衝進行通訊時不再需要考慮同步問題.使用方便,但是資訊的複製需要額外消耗cpu的時間.不適宜於資訊量大或操作頻繁的場合。

3.共享記憶體針對訊息緩衝的缺點改而利用記憶體緩衝區直接交換資訊,無須複製,快捷、資訊量大是其優點。但是共享記憶體的通訊方式是通過將共享的記憶體緩衝區直接附加到程序的虛擬位址空間中來實現的.因此,這些程序之間的讀寫操作的同步問題作業系統無法實現。必須由各程序利用其他同步工具解決。另外,由於記憶體實體存在於計算機系統中.所以只能由處於同乙個計算機系統中的諸程序共享。不方便網路通訊。

補充:1.

# 管道( pipe ):管道是一種半雙工的通訊方式,資料只能單向流動,而且只能在具有親緣關係的程序間使用。程序的親緣關係通常是指父子程序關係。

# 有名管道 (named pipe) : 有名管道也是半雙工的通訊方式,但是它允許無親緣關係程序間的通訊。

# 訊號量( semophore ) : 訊號量是乙個計數器,可以用來控制多個程序對共享資源的訪問。它常作為一種鎖機制,防止某程序正在訪問共享資源時,其他程序也訪問該資源。因此,主要作為程序間以及同一程序內不同執行緒之間的同步手段。

# 訊息佇列( message queue ) : 訊息佇列是由訊息的鍊錶,存放在核心中並由訊息佇列識別符號標識。訊息佇列克服了訊號傳遞資訊少、管道只能承載無格式位元組流以及緩衝區大小受限等缺點。

# 訊號 ( sinal ) : 訊號是一種比較複雜的通訊方式,用於通知接收程序某個事件已經發生。

#共享記憶體( shared memory):共享記憶體就是對映一段能被其他程序所訪問的記憶體,這段共享記憶體由乙個程序建立,但多個程序都可以訪問。共享記憶體是最快的ipc方式,它是針對其他程序間通訊方式執行效率低而專門設計的。它往往與其他通訊機制,如訊號量,配合使用,來實現程序間的同步和通訊。# 套接字( socket ) : 套解口也是一種程序間通訊機制,與其他通訊機制不同的是,它可用於不同及其間的程序通訊。

管道的主要侷限性正體現在它的特點上:

只支援單向資料流;

只能用於具有親緣關係的程序之間;

沒有名字;

管道的緩衝區是有限的(管道制存在於記憶體中,在管道建立時,為緩衝區分配乙個頁面大小);

管道所傳送的是無格式位元組流,這就要求管道的讀出方和寫入方必須事先約定好資料的格式,比如多少位元組算作乙個訊息(或命令、或記錄)等等;

2.用於程序間通訊(ipc)的四種不同技術: 

1. 訊息傳遞(管道,fifo,posix和system v訊息佇列) 

2. 同步(互斥鎖,條件變數,讀寫鎖,檔案和記錄鎖,posix和system v訊號燈) 

3. 共享記憶體區(匿名共享記憶體區,有名posix共享記憶體區,有名system v共享記憶體區) 

4. 過程呼叫(solaris門,sun rpc) 

訊息佇列和過程呼叫往往單獨使用,也就是說它們通常提供了自己的同步機制.相反,共享記憶體區通常需要由應用程式提供的某種同步形式才能正常工作.解決某個特定問題應使用哪種ipc不存在簡單的判定,應該逐漸熟悉各種ipc形式提供的機制,然後根據特定應用的要求比較它們的特性. 

必須考慮的四個前提: 

1. 聯網的還是非聯網的.ipc適用於單台主機上的程序或執行緒間的.如果應用程式有可能分布到多台主機上,那就要考慮使用套接字代替ipc,從而簡化以後向聯網的應用程式轉移的工作. 

2. 可移植性. 

3. 效能,在具體的開發環境下執行測試程式,比較幾種ipc的效能差異. 

4. 實時排程.如果需要這一特性,而且所用的系統也支援posix實時排程選項,那就考慮使用posix的訊息傳遞和同步函式. 

各種ipc之間的一些主要差異: 

1. 管道和fifo是位元組流,沒有訊息邊界.posix訊息和system v訊息則有從傳送者向接受者維護的記錄邊界(eg:tcp是沒有記錄邊界的位元組流,udp則提供具有記錄邊界的訊息). 

2. 當有乙個訊息放置到乙個空佇列中時,posix訊息佇列可向乙個程序傳送乙個訊號,或者啟動乙個新的執行緒.system v則不提供類似的通知形式. 

3. 管道和fifo的資料位元組是先進先出的.posix訊息和system v訊息具有由傳送者賦予的優先順序.從乙個posix訊息佇列讀出時,首先返回的總是優先順序最高的訊息.從乙個system v訊息佇列讀出時,讀出者可以要求想要的任意優先順序的訊息. 

4. 在眾多的訊息傳遞技術—管道,fifo,posix訊息佇列和system v訊息佇列—中,可從乙個訊號處理程式中呼叫的函式只有read和write(適用於管道和fifo). 

比較不同形式的訊息傳遞時,我們感興趣的有兩種測量尺度: 

1.頻寬(bandwidth):資料通過ipc通道轉移的速度.為測量該值,我們從乙個程序向另乙個程序傳送大量資料(幾百萬位元組).我們還給不同大小的i/o操作(例如管道和fifo的write和read操作)測量該值,期待發現頻寬隨每個i/o操作的資料量的增長而增長的規律. 

2. 延遲(latency):乙個小的ipc訊息從乙個程序到令乙個程序再返回來所花的時間.我們測量的是只有乙個1個位元組的訊息從乙個程序到令乙個程序再回來的時間(往返時間) 

在現實世界中,頻寬告訴我們大塊資料通過乙個ipc通道傳送出去需花多長時間,然而ipc也用於傳遞小的控制資訊,系統處理這些小訊息所需的時間就由延遲提供.這兩個數都很重要.

Linux高階程序間通訊 紀錄鎖

加鎖與解鎖 lockit demonstration of fcntl locking include include include includeint main void printf parent locked record n switch fork printf child locked...

Linux程序間通訊(3) 訊息佇列

由核心建立的用於存放訊息的鍊錶,分為 system v訊息佇列,posix訊息佇列。對posix訊息佇列的讀總是返回最高優先順序的最早訊息。對system v訊息佇列的讀可以返回任意指定優先順序的訊息 使用步驟 使用mesgget函式建立新的訊息佇列,或者獲取已存在的訊息佇列,並返回唯一標識,後續收...

Linux程序間通訊

程序間通訊 ipc interprocess communication 基本機制 訊號 管道及命名管道 訊息佇列 共享主存 訊號量 套接字。訊號 全稱軟中斷訊號,是在軟體層次上對中斷機制的一種模擬,它也是程序間通訊機制中唯一的非同步通訊機制。linux訊號處理函式可分為訊號安裝函式 訊號傳送函式和...