程式通訊方式總結與盤點

李子樹_發表於2020-02-14

​ 程式通訊是指程式之間的資訊交換。這裡需要和程式同步做一下區分,程式同步控制多個程式按一定順序執行,程式通訊是一種手段,而程式同步是目標。從某方面來講,程式通訊可以解決程式同步問題。

​ 首先回顧下我們前面博文中講到的訊號量機制,為了實現程式的互斥與同步,需要在程式間交換一定的資訊,因此訊號量機制也可以被歸為程式通訊的一種方式,但是也被稱為低階程式通訊,主要原因為:

  1. 效率低:一次只可操作少量的共享資料,比如生產者消費者問題,生產者一次只可向緩衝池中投放一個訊息;
  2. 通訊對使用者不透明:OS只為程式提供了共享儲存器,而關於程式之間通訊所需的共享資料結構的設計、資料的傳遞、程式的互斥與同步,都必須要有開發者去實現,顯然,這對開發者來說很不方便,增加了程式設計的難度和複雜度。

​ 既然是說到了低階程式通訊,並且解釋了原因,那我們也來看一下高階程式通訊的特點:

  1. 使用方便:這也是針對低階程式通訊中的第二點—通訊對使用者不透明,OS對開發者隱藏了程式通訊的具體細節,對於使用者來說,只需要使用有OS提供的一組原語(實現高階通訊的命令),就可以方便的直接使用並實現程式間的通訊。就像我麼使用第三方的jar包一樣,直接呼叫封裝好的方法即可。
  2. 高效的傳送大量資料:可以通過OS提供的原語快速的傳輸大量資料。

​ 說完了兩種級別的程式通訊,下面我們就具體的來看一看程式的通訊方式都有哪些。通訊機制也是隨著OS的發展而不斷進步的,目前通訊機制可分為四大類:共享儲存器系統、管道通訊系統、訊息傳遞系統以及客戶機-伺服器系統。我們依次來進行講解,對於下面出現的每種通訊方式,我們採用序號來進行標記。

共享儲存器系統

​ 在共享儲存器系統中,相互通訊的程式共享某些資料結構或共享儲存區,程式之間能夠通過這些空間進行通訊。因此按照共享內容的不同,可將其分為以下兩種型別:

1.基於共享資料結構的通訊方式

​ 也稱為我們上面講到的訊號量機制,此方式要求諸程式共用某些資料結構,藉以實現程式間的資訊交換,共享資料結構的一個例子就是存放訊息的共享緩衝池,對其的操作需要使用訊號量來保證諸程式間同步的進行。

2.基於共享資料區的通訊方式

​ 為了傳輸大量資料,OS在記憶體中劃出一塊共享儲存區域,諸程式通過該共享區域讀或寫交換資訊,實現通訊。資料的形式、位置、訪問控制都是由程式來控制的。需要通訊的程式在通訊前,先向系統申請獲得共享儲存區的一個分割槽,並將其附加到自己的地址空間中(如果不新增,訪問時會產生地址越界中斷,後續的記憶體管理中進行詳細講解),便可對其中的資料進行正常的讀、寫,操作完成或者不在需要時,再講分割槽歸還給共享儲存區。也因為其一次可以操作一個分割槽,並可將大量的資料讀取或者寫入分割槽,所以這種方式也屬於高階通訊。另外因為資料不需要在程式之間複製,所以這是最快的一種程式通訊機制

管道(pipe)通訊系統

​ 所謂“管道”是指連線一個讀程式和一個寫程式以實現他們之間通訊的一個共享檔案,又名pipe檔案。管道系統可分為兩種:

3.無名管道

​ 這是Unix早期的一種通訊方式,是半雙工通訊,只能用於父子程式或兄弟程式間,並且它不是普通的檔案,並不屬於其他任何檔案系統,並且只存在於記憶體中。

程式通訊方式總結與盤點

4.命名管道(FIFO)

​ 可以用於在無關程式間交換資料,FIFO也就是先進先出,有路徑名與命名管道關聯,它以一種特殊裝置形式存在於檔案系統中,並且可以實現半雙工或全雙工的通訊。FIFO 常用於客戶-伺服器應用程式中,被作為匯聚點,在客戶程式和伺服器程式之間傳遞資料。

程式通訊方式總結與盤點

訊息傳遞系統

​ 在該機制中,程式不必藉助任何共享儲存區或資料結構,而是以格式化的訊息(message)為單位,將通訊的資料封裝在訊息中,並利用OS提供的一組通訊原語,在程式間進行訊息傳遞,完成程式間的資料交換。

​ 該方式隱藏了通訊細節,使通訊過程對使用者透明化,降低了程式設計的複雜性和錯誤率,這也讓它成為當前應用最廣泛的一類程式間通訊機制;並且該機制可以很好的支援多處理機系統、分散式系統和計算機網路,下面我們按照其實現方式,來分別講解下訊息傳遞系統:

5.直接通訊方式(訊息緩衝佇列)

​ 直接通訊方式,是直接通過原語將訊息傳送到指定的程式,因此要求放鬆和接收的程式都必須以顯示的方式提供對方的識別符號。下面是兩個OS提供的兩條通訊原語:

send(receiver, message);   //傳送一個訊息給接收程式
receive(sender, message);  //接收sender發來的訊息

​ 下圖是一個直接通訊方式的示意圖,圖中可以很清晰的看到程式P1和P2各自傳送了一條訊息給對方,並從對方那接收了一條訊息。

程式通訊方式總結與盤點
​ 需要注意的是,**訊息緩衝佇列通訊機制**是直接通訊的一種實現方式,而不是間接通訊,因為其是將訊息直接傳送到指定程式中,如果訊息沒來得及被取走,就放入到訊息緩衝佇列中,因此和我們理解的ActiveMQ、RocketMQ是不同的。

6.間接通訊方式(訊息佇列)

​ 間接通訊方式是指傳送和接收程式都通過共享中間實體(OS中稱為信箱)的方式進行訊息的傳送和接收,完成程式間的通訊。

​ 我們來看下信箱通訊的一個示意圖,從圖中我們可以看到,兩個程式通過信箱來進行訊息的傳送和接收。

程式通訊方式總結與盤點

​ 我們現在常用的訊息佇列比如ActiveMQ、RocketMQ、RabbitMQ等,都是間接通訊的一種,通過這種共享的中間實體(不一定要在當前主機的記憶體中),可以實現程式間的通訊,並且可以很容易的實現不同主機上的程式通訊。

客戶機-伺服器系統

​ 講到客戶機-伺服器系統,大家可能都會想到C/S架構,想到的可能是QQ或者WinForm等應用,但是C/S模式是一個邏輯上的概念,在程式通訊中,發起請求的程式為客戶機,進行響應的程式為伺服器,在客戶機-伺服器系統中,除了客戶機和伺服器,還有用與連線所有客戶機和伺服器的網路系統。在網路環境的各種應用領域,客戶機-伺服器系統已經成為當前主流的通訊機制。

​ 其主要的方法有三類:套接字、遠端過程呼叫和遠端方法呼叫。

7.套接字(Socket)

​ 說起套接字大家應該都比較熟悉,ip+port,可以定位到哪個主機下的哪個程式,這樣就可以對其進行請求,這個就是網路套接字。另一種套接字是檔案套接字,基於本地檔案系統實現的,一個套接字關聯到一個特殊檔案,通訊雙放通過這個檔案進行讀寫實現通訊,其原理類似管道。

​ 套接字的優勢就在於,他不僅適用於同一臺計算機內部的程式通訊,也適用於網路環境中不同計算機間的程式通訊;可以保證通訊雙方邏輯鏈路的唯一性(ip+port對ip+port可以保證邏輯鏈路唯一),並與實現資料傳輸的併發服務;隱藏了通訊設施及實現細節,採用統一的介面進行處理。

8.遠端過程呼叫和遠端方法呼叫(RPC)

​ 遠端過程呼叫RPC(Remote Procedure Call)是一個通訊協議,用於通過網路連線的系統。該協議允許執行於一臺主機(本地)系統上的程式呼叫另一臺主機(遠端)系統上的程式,而對開發人員表現為常規的過程呼叫,無須額外的為此程式設計。如果設計的軟體採用物件導向程式設計,也可稱之為遠端方法呼叫

總結

​ 最後,我們對這幾種通訊方式進行一個總結,其中的某幾種通訊方式,被別的博主同一成了一個,比如訊息傳遞系統中的直接通訊和間接通訊,統稱為訊息佇列,這裡不做正確性的評價,本文是把所有的通訊機制大的方向做一個總結,具體的實現方式是有很多種的,故不做一一敘述。

1.共享資料結構(訊號量):僅適用於傳遞相對少量的資料,通訊效率低,屬於低階通訊;

2.共享儲存區:允許多個程式共享一個給定的儲存區,可以從中申請快取區。因為資料不需要在程式之間複製,所以這是最快的一種通訊機制,但要對諸程式的訪問進行同步控制;

3.無名管道:半雙工、速度慢,容量有限,只有父子程式能通訊;

4.命名管道(FIFO):任何程式間都能通訊,但速度慢 ,可以實現半雙工或全雙工通訊;

5.訊息緩衝佇列:直接使用OS提供的原語,隱藏通訊細節,需要知道接收程式的id和傳送程式的id;

6.訊息佇列:直接通過共享信箱或者佇列,兩個程式可以實現通訊,可實現實時和非實時通訊,兩種訊息傳遞系統容量都容易收到系統的限制;

7.Socket:可以用於本機和不同主機間的程式通訊,隱藏通訊細節;

8.RPC:無須額外程式設計,隱藏通訊細節。


​ 又到了分隔線以下,本文到此就結束了,本文內容全部都是由博主自己進行整理並結合自身的理解進行總結,如果有什麼錯誤,還請批評指正。對其中有什麼疑惑的,可以評論區留言,歡迎你的留言與討論;另外原創不易,如果本文對你有所幫助,還請留下個贊,以表支援。

​ 如有興趣,還可以檢視我的其他幾篇部落格,都是OS的乾貨(目錄),喜歡的話還請點贊、評論加關注_

相關文章