天天看點

Linux程序間通信的幾種方式總結--linux核心剖析(七) 程序間通信概述 管道( pipe ) 信号量( semophore ) 消息隊列( message queue ) 信号 ( singal ) 共享記憶體( shared memory ) 套接字( socket ) 程序間通信各種方式效率比較

資料傳輸

一個程序需要将它的資料發送給另一個程序,發送的資料量在一個位元組到幾m位元組之間

共享資料

多個程序想要操作共享資料,一個程序對共享資料

通知事

一個程序需要向另一個或一組程序發送消息,通知它(它們)發生了某種事件(如程序終止時要通知父程序)。

資源共享

多個程序之間共享同樣的資源。為了作到這一點,需要核心提供鎖和同步機制。

程序控制

有些程序希望完全控制另一個程序的執行(如debug程序),此時控制程序希望能夠攔截另一個程序的所有陷入和異常,并能夠及時知道它的狀态改變。

linux下的程序通信手段基本上是從unix平台上的程序通信手段繼承而來的。而對unix發展做出重大貢獻的兩大主力at&t的貝爾實驗室及bsd(加州大學伯克利分校的伯克利軟體釋出中心)在程序間通信方面的側重點有所不同。 前者對unix早期的程序間通信手段進行了系統的改進和擴充,形成了“system v ipc”,通信程序局限在單個計算機内; 後者則跳過了該限制,形成了基于套接口(socket)的程序間通信機制。 linux則把兩者繼承了下來

早期unix程序間通信

基于system v程序間通信

基于socket程序間通信

posix程序間通信。

unix程序間通信方式包括:管道、fifo、信号。

system v程序間通信方式包括:system v消息隊列、system v信号燈、system v共享記憶體

posix程序間通信包括:posix消息隊列、posix信号燈、posix共享記憶體。

由于unix版本的多樣性,電子電氣工程協會(ieee)開發了一個獨立的unix标準,這個新的ansi unix标準被稱為計算機環境的可移植性作業系統界面(psoix)。現有大部分unix和流行版本都是遵循posix标準的,而linux從一開始就遵循posix标準; bsd并不是沒有涉足單機内的程序間通信(socket本身就可以用于單機内的程序間通信)。事實上,很多unix版本的單機ipc留有bsd的痕迹,如4.4bsd支援的匿名記憶體映射、4.3+bsd對可靠信号語義的實作等等。

管道(pipe),流管道(s_pipe)和有名管道(fifo)

信号(signal)

消息隊列

共享記憶體

信号量

套接字(socket)

管道這種通訊方式有兩種限制,一是半雙工的通信,資料隻能單向流動,二是隻能在具有親緣關系的程序間使用。程序的親緣關系通常是指父子程序關系。

流管道s_pipe: 去除了第一種限制,可以雙向傳輸.

管道可用于具有親緣關系程序間的通信,命名管道:name_pipe克服了管道沒有名字的限制,是以,除具有管道所具有的功能外,它還允許無親緣關系程序間的通信;

信号量是一個計數器,可以用來控制多個程序對共享資源的通路。它常作為一種鎖機制,防止某程序正在通路共享資源時,其他程序也通路該資源。是以,主要作為程序間以及同一程序内不同線程之間的同步手段。

信号是比較複雜的通信方式,用于通知接受程序有某種事件發生,除了用于程序間通信外,程序還可以發送信号給程序本身;linux除了支援unix早期信号語義函數sigal外,還支援語義符合posix.1标準的信号函數sigaction(實際上,該函數是基于bsd的,bsd為了實作可靠信号機制,又能夠統一對外接口,用sigaction函數重新實作了signal函數);

消息隊列是由消息的連結清單,存放在核心中并由消息隊列辨別符辨別。消息隊列克服了信号傳遞資訊少、管道隻能承載無格式位元組流以及緩沖區大小受限等缺點。

消息隊列是消息的連結表,包括posix消息隊列system v消息隊列。有足夠權限的程序可以向隊列中添加消息,被賦予讀權限的程序則可以讀走隊列中的消息。消息隊列克服了信号承載資訊量少,管道隻能承載無格式位元組流以及緩沖區大小受限等缺點。

信号是一種比較複雜的通信方式,用于通知接收程序某個事件已經發生。

主要作為程序間以及同一程序不同線程之間的同步手段。

共享記憶體就是映射一段能被其他程序所通路的記憶體,這段共享記憶體由一個程序建立,但多個程序都可以通路。共享記憶體是最快的 ipc 方式,它是針對其他程序間通信方式運作效率低而專門設計的。它往往與其他通信機制,如信号量,配合使用,來實作程序間的同步和通信。

使得多個程序可以通路同一塊記憶體空間,是最快的可用ipc形式。是針對其他通信機制運作效率較低而設計的。往往與其它通信機制,如信号量結合使用,來達到程序間的同步及互斥。

套解口也是一種程序間通信機制,與其他通信機制不同的是,它可用于不同機器間的程序通信

更為一般的程序間通信機制,可用于不同機器之間的程序間通信。起初是由unix系統的bsd分支開發出來的,但現在一般可以移植到其它類unix系統上:linux和system v的變種都支援套接字。

類型

無連接配接

可靠

流控制

記錄消息類型

優先級

普通pipe

n

y

流pipe

命名pipe(fifo)

共享存儲

unix流socket

unix資料包socket

注:無連接配接: 指無需調用某種形式的open,就有發送消息的能力流控制: 如果系統資源短缺或者不能接收更多消息,則發送程序能進行流量控制

各種通信方式的比較和優缺點

管道:速度慢,容量有限,隻有父子程序能通訊

fifo:任何程序間都能通訊,但速度慢

消息隊列:容量受到系統限制,且要注意第一次讀的時候,要考慮上一次沒有讀完資料的問題

信号量:不能傳遞複雜消息,隻能用來同步

共享記憶體區:能夠很容易控制容量,速度快,但要保持同步,比如一個程序在寫的時候,另一個程序要注意讀寫的問題,相當于線程中的線程安全,當然,共享記憶體區同樣可以用作線程間通訊,不過沒這個必要,線程間本來就已經共享了同一程序内的一塊記憶體

如果使用者傳遞的資訊較少或是需要通過信号來觸發某些行為.前文提到的軟中斷信号機制不失為一種簡捷有效的程序間通信方式.

但若是程序間要求傳遞的資訊量比較大或者程序間存在交換資料的要求,那就需要考慮别的通信方式了。

無名管道簡單友善.但局限于單向通信的工作方式.并且隻能在建立它的程序及其子孫程序之間實作管道的共享:

有名管道雖然可以提供給任意關系的程序使用.但是由于其長期存在于系統之中,使用不當容易出錯.是以普通使用者一般不建議使用。

消息緩沖可以不再局限于父子程序,而允許任意程序通過共享消息隊列來實作程序間通信,并由系統調用函數來實作消息發送和接收之間的同步,進而使得使用者在使用消息緩沖進行通信時不再需要考慮同步問題,使用友善,但是資訊的複制需要額外消耗cpu的時間,不适宜于資訊量大或操作頻繁的場合。

共享記憶體針對消息緩沖的缺點改而利用記憶體緩沖區直接交換資訊,無須複制,快捷、資訊量大是其優點。

但是共享記憶體的通信方式是通過将共享的記憶體緩沖區直接附加到程序的虛拟位址空間中來實作的,是以,這些程序之間的讀寫操作的同步問題作業系統無法實作。必須由各程序利用其他同步工具解決。另外,由于記憶體實體存在于計算機系統中,是以隻能由處于同一個計算機系統中的諸程序共享。不友善網絡通信。

共享記憶體塊提供了在任意數量的程序之間進行高效雙向通信的機制。每個使用者都可以讀取寫入資料,但是所有程式之間必須達成并遵守一定的協定,以防止諸如在讀取資訊之前覆寫記憶體空間等競争狀态的出現。

不幸的是,linux無法嚴格保證提供對共享記憶體塊的獨占通路,甚至是在您通過使用ipc_private建立新的共享記憶體塊的時候也不能保證通路的獨占性。 同時,多個使用共享記憶體塊的程序之間必須協調使用同一個鍵值。

轉載:http://blog.csdn.net/gatieme/article/details/50908749

繼續閱讀