在上一篇裡,使用了讀寫檔案的方式來實作程序間通信,使用了信号量完成了程序間的同步,雖然這種實作方式也能夠完成任務,但是缺點就在于它需要讀寫磁盤。是以 linux 系統提供了多種多樣的程序間通信的手段,幫助我們實作程序間通信。
不過,在講解 Linux 程序間通信(後面簡稱 Linux IPC)之前,需要了解 Linux IPC的分類。
1. Linux IPC 分類
說分類不太準确,不過還是先按照此方式大概講一下,友善初學者初步了解。linux ipc 大緻可以分為下面四類:
- 最初的 Unix IPC:主要包括無名管道,有名管道,信号(上一個專題講過)。
- System V IPC:主要包括 System V 共享記憶體、System V 消息隊列、System V 信号量。
- 基于 socket IPC:主要使用套接字的方式進行通信。
- POSIX IPC:POSIX 共享記憶體、POSIX 消息隊列、POSIX 信号量。
初學者可能有點懵圈,怎麼有這麼多,共享記憶體還分成 System V 和 POSIX 的?準确的說,Linux 是繼承了先輩們的基因,它把 System V IPC 、POSIX 等等 IPC 的方式都實作了。這意味着,在實際程式設計的時候,你可以根據你自己的口味,選擇一款你喜歡的方式。比如,System V 的共享記憶體和消息隊列用起來比較友善,我就喜歡用它,而 System V 信号量用起來麻煩,我可以選擇使用 POSIX 信号量,它的接口更加簡單。
下面這張圖說明了 Linux IPC 的曆史(這才是準确的說法,說分類本身不恰當,但是學習的時候可以這樣用):

linux下的程序通信手段基本上是從Unix平台上的程序通信手段繼承而來的。而對Unix發展做出重大貢獻的兩大主力 AT&T 的貝爾實驗室及 BSD(加州大學伯克利分校的伯克利軟體釋出中心)在程序間通信方面的側重點有所不同。前者對Unix早期的程序間通信手段進行了系統的改進和擴充,形成了“System V IPC”,通信程序局限在單個計算機内;後者則跳過了該限制,形成了基于套接口(socket)的程序間通信機制。Linux則把兩者繼承了下來。
2. Linux IPC 常用手段
- 無名管道(pipe)及有名管道(named pipe):無名管道隻能用于有親緣關系的程序,有名管道用于任意兩程序間通信。
- 信号(signal):上一個專題講的很詳細了。
- 消息(message)隊列:包括Posix消息隊列system V消息隊列。消息隊列克服了信号承載資訊量少,管道隻能承載無格式位元組流以及緩沖區大小受限等缺點。
- 共享記憶體(share memory):使得多個程序可以通路同一塊記憶體空間,是最快的可用IPC形式。是針對其他通信機制運作效率較低而設計的。往往與其它通信機制,如信号量結合使用,來達到程序間的同步及互斥。
- 信号量(semaphore):主要作為程序間以及同一程序不同線程之間的同步手段。
- 套接口(Socket):更為一般的程序間通信機制,可用于不同機器之間的程序間通信。起初是由Unix系統的BSD分支開發出來的,但現在一般可以移植到其它類Unix系統上:Linux和System V的變種都支援套接字。
3. 總結
- 知道 Linux IPC 曆史(或者說分類)
- 知道 Linux IPC 常用手段