1. 程式人生 > >理解幾種常見的程序間通訊方式

理解幾種常見的程序間通訊方式

什麼是程序間通訊

廣義上講,程序間通訊(Inter-Process Communication, IPC)是指執行在不同程序(不論是否在同一臺機器)中的若干執行緒間的資料交換。

從上面的定義可以得出兩點:

  • 參與通訊的程序即可以執行在同一臺機器上,也可以執行在各自的裝置環境中(Remote Procedure Call Protocol, RPC)。如果程序是跨機器執行的,則通常是由網路連線在一起。
  • 實現方式可以有多種多樣。原則上,任何跨程序的資料交換都可以稱為程序間通訊。

常見的幾種程序間通訊方式

共享記憶體(Shared Memory)

共享記憶體是一種常見的程序間通訊機制。由於兩個程序可以直接訪問同一塊兒記憶體區域,減少了資料的複製操作,因而在速度上的優勢比較明顯。

一般情況下,實現記憶體共享的步驟如下:

  1. 建立記憶體共享區

    記憶體共享區存在於核心中

  2. 對映記憶體共享區

    需要將記憶體共享區對映到程序的空間中才可以進一步操作

  3. 訪問記憶體共享區

  4. 程序間通訊

    由於記憶體共享本身並沒有提供同步機制,所遇參與通訊的各個程序需要自己協商處理。

  5. 撤銷記憶體對映區

  6. 刪除記憶體共享區

管道(Pipe)

管道這個詞很形象地描述了通訊雙方的行為:

  • 分別處於管道的兩方,進行資料傳輸通訊。
  • 管道是單向的,如果一個程序既要讀又要寫,需要建立兩根管道。類似於水管的特性。
  • 管道的兩端分別為”讀取端”(read end)和”寫入端”(write end)。

管道的侷限性

  • 生命週期是隨程序結束而完結
  • 只能用於具有親緣關係的程序通訊
  • 管道是匿名的,沒有名字

為了克服管道上述的侷限性,可以使用命名管道(Named Pipe)。它具有管道所有的功能,並且沒有管道的上述侷限。

套接字(Socket)

其實網路通訊中所使用的API與跨程序使用的是完全一樣的。

兩種角色:伺服器與客戶端。
每種角色的大致流程如下:

伺服器:

  • Create socket - socket()
  • Bind sockaddr - bind()
  • Listen - listen()
  • Wait & Accept
    • 一般在一個迴圈裡邊監聽是否有新的連線 - accept();然後可以讀寫了
    • 讀 - recv()
    • 寫 - send()
    • 關閉連線與客戶端的連線 - close()
  • 釋放socket close()

客戶端:

  • Create socket - socket()
  • Bind sockaddr - bind()
  • 連線伺服器 - accept();然後可以讀寫了
  • 讀 recv()
  • 寫 send()
  • 關閉連線 close()

注意,如果伺服器與客戶端在同一臺主機上,則是跨程序通訊。如果在不同的主機上,則變成了網路通訊。

訊息佇列(Message Queue)

訊號(Signal)

訊號量(Semophore)

參考