程序通訊概念簡介 多執行緒上篇(六)
程序通訊就相當於一種工作方式、溝通形式 , 比如你給我一個SVN標籤號並且告知我意圖,我去庫中檢索指定標籤修改的指定內容,就完成了一個任務的協作。
程序同步中,也有資訊的交換,比如互斥量訪問,再比如生產者和消費者,共享緩衝池,但是這些通常被稱之為低階的程序通訊。
以訊號量為例,如果你說我在塔頂點亮燈表示危險,否則表示安全,這沒問題,如果你想用燈亮燈滅來像QQ一樣,大段大段的傳遞訊息可能麼?
多搞幾盞燈?然後用編碼?即使那樣你依然是很費力的。
所以說盡管比如訊號量機制作為同步工具是卓有成效的,但作為通訊工具,則不夠方便
首先是效率低,另外共享資料結構的設定、資料的傳送、程序的互斥與同步等,都必須由程式設計師自己去實現
所以,對於程序間的通訊,我們迫切的渴望有“封裝好的方法”
程序通訊主要指的就是作業系統提供的程序通訊工具(“封裝好的方法”)用來程序間的資訊交換。
程序通訊型別
主要有四種通訊方式
共享儲存器系統
共享儲存系統關鍵在於共享
主要兩種:
- 共享資料結構
- 共享儲存區
管道通訊
這種方式 首創於UNIX 系統 , 由於它能有效地傳送大量資料,因而又被引入到許多其它的作業系統中
管道指用於連線一個讀程序和一個寫程序以實現它們之間通訊的一個共享檔案,這個檔案又被叫做pipe檔案
管道可以理解為一種比較特殊的“共享儲存器系統”的通訊方式
訊息傳遞系統
在該機制中,程序不必藉助任何共享儲存區或資料結構,而是以格式化的訊息(message)為單位,將通訊的資料封裝在訊息中
並利用作業系統提供的一組通訊命令(原語),在程序間進行訊息傳遞,完成程序間的資料交換
計算機網路中的報文就是一種message
訊息傳遞系統中的訊息,其實也是“共享資料結構”的一種形式,是一種特殊的形式
因為被共享的資料結構而不是隨便自定義的,而是大家共同設計好的,認可的,一致的一種格式。
基於這種一致性的格式,然後作業系統對他提供了支援
所以,他就是共享資料結構的一個特例,這個特例使用更加方便簡單。
簡單說,計算機報文是一種message,那麼作業系統對整個TCP/IP協議棧的實現,這就是通訊命令,封裝了底層的傳輸細節,對開發者來說是透明的
客戶伺服器系統
客戶機一伺服器系統的通訊機制,在網路環境的各種應用領域已成為當前主流的通訊實現機制
BS架構的系統本質也是包裝演化的CS,瀏覽器難道不是客戶端軟體麼
主要有三種:
- 套接字
- 遠端過程呼叫
- 遠端方法呼叫
遠端過程呼叫 RPC(Remote Procedure Call),RPC採用客戶機/伺服器模式,請求程式就是一個客戶機,而服務提供程式就是一個伺服器
RPC允許你 透明的 呼叫遠端伺服器上提供的服務
對於面向物件的程式設計中,遠端過程呼叫通常也被稱為遠端方法呼叫
比如java1.1中實現的Remote Method Invocation,RMI,可以認為是RPC的Java版本,RMI大大增強了Java開發分散式應用的能力。
概括地說的話:
遠端過程呼叫RPC是一種協議概念,它是一種通過網路從遠端計算機程式上請求服務,而不需要了解底層網路技術的協議。
RPC不依賴於具體的網路傳輸協議,tcp、udp等都可以。
協議必然需要被實現才能使用,他只是一種協議與標準,RMI就相當於是sun對RPC的一個Java實現
Socket是應用層與TCP/IP協議族通訊的中間軟體抽象層,是更加底層的通訊工具,所以可以認為RPC是socket的上層建築
一個或許不是很合適的比喻:如果RPC是議論文格式,那麼RMI可能是漢語的議論文,socket可能是漢字
套接字原理步驟
雙方程序執行在不同主機的網路環境下,被分配了一對套接字,一個屬於接收程序(或伺服器端),一個屬於傳送程序(或客戶端)。
傳送程序(或客戶端)發出連線請求時,隨機申請一個套接字,主機為之分配一個埠,與該套接字繫結,不再分配給其它程序。
接收程序(或伺服器端)擁有全域性公認的套接字和指定的埠(如ftp伺服器監聽埠為21,Web或http伺服器監聽埠為80),並通過監聽埠等待客戶請求。因此,任何程序都可以向它發出連線請求和資訊請求,以方便程序之間通訊連線的建立。
接收程序(或伺服器端)一旦收到請求,就接受來自發送程序(或客戶端)的連線,完成連線,即在主機間傳輸的資料可以準確地傳送到通訊程序,實現程序間的通訊;
當通訊結束時,系統通過關閉接收程序(或伺服器端)的套接字撤銷連線。
遠端過程原理步驟
負責RPC的呼叫的程序有兩個,一個是本地客戶程序,另一個是遠端服務程序,這兩個程序也被稱之為網路守護程序,主要負責網路之間的訊息傳遞
通常處於阻塞之中,等待訊息。
而遠端過程呼叫的透明化核心就是所謂的存根,也叫做 樁stub
所以說兩個程序和兩個存根是RPC的根本
樁的原理
樁類似代理者、轉換器一類的角色
舉一個例子:在一些與底層硬體晶片等互動的軟體層,軟體層依賴底層晶片的處理,如何更方便的進行程式碼測試?
也就是相當於A類中有方法functionA,B類中有方法functionB(假定functionB 是硬體處理部分,測試並不方便,需要依賴裝置)
functionA(){
functionB();
}
我們就可以編寫一個新的類C,提供樁方法:functionStubC,所有呼叫functionB的地方全部使用functionStubC,也就是
functionA(){
functionStubC();
}
而functionStubC的返回值,永遠是functionB成功的返回值。
這就是一個打樁的概念。
RPC也是通過這個樁的概念來實現透明的遠端過程呼叫
對本地呼叫來說,他看到的只是客戶端存根(stub)
就如同我們上面的functionStubC,當然比functionStubC要更加複雜,所有的處理都在他背後被執行
所以對本地呼叫來說是透明的
RPC過程步驟
- 本地過程呼叫者以一般方式呼叫遠端過程在本地關聯的客戶存根,傳遞相應的引數,然後將控制權轉移給客戶存根;
- 客戶存根執行,完成包括過程名和呼叫引數等資訊的訊息建立,將控制權轉移給本地客戶程序;
- 本地客戶程序完成與伺服器的訊息傳遞,將訊息傳送到遠端伺服器程序;
- 遠端伺服器程序接收訊息後轉入執行,並根據其中的遠端過程名找到對應的伺服器存根,將訊息轉給該存根;
- 該伺服器存根接到訊息後,由阻塞狀態轉入執行狀態,拆開訊息從中取出過程呼叫的引數,然後以一般方式呼叫伺服器上關聯的過程;
- 在伺服器端的遠端過程執行完畢後,將結果返回給與之關聯的伺服器存根;
- 該伺服器存根獲得控制權執行,將結果打包為訊息,並將控制權轉移給遠端伺服器程序:
- 遠端伺服器程序將訊息傳送回客戶端;
- 本地客戶程序接收到訊息後,根據其中的過程名將訊息存入關聯的客戶存根,再將控制權轉移給客戶存根;
- 客戶存根從訊息中取出結果,返回給本地呼叫者程序,並完成控制權的轉移。
總結
程序通訊的一些核心思想與基本形式就是上面的這些簡介
這些是最純粹基本的理論知識,而對於我們實際的開發中,面對的總是各種各樣的對於現存的理論的實現版本
核心仍舊是依賴作業系統以及語言本身的實現以及一些框架等
但是理解這些概念是必要的,能讓你後續的學習路線越來越明朗,技術是層不出窮的,你僅僅學習招式,永遠也無法窮盡,還導致自己沒有底蘊。
原文地址: 程序通訊概念簡介 多執行緒上篇(六)