第六章-----程式通訊

飄過的小熊發表於2016-09-04

第六章—–程式通訊

標籤(空格分隔): 作業系統之哲學原理



為什麼要通訊

人類是受不了不交流的,當然程式作為人類的發明,自然是免不了脫離人類的習性,也有通訊需求。滿滿的都是套路,程式之間的通訊叫做程式間通訊(Inter-Process Communication,IPC)

人類的通訊方式無外乎對白,打手勢,寫信,發電報,擁抱等方法(與後面要介紹的內容是無縫對接)


程式對白:管道,記名管道,套接字

程式對白:就是一個程式發出某種資料資訊,另一方接受資料資訊,而這些資訊通過一片共享的儲存空間進行傳遞。這片儲存空間就可以抽象為管道

如何建立一個管道?

要建立一個管道,一個程式只需呼叫管道建立的系統呼叫即可。該系統呼叫所做的事情就是在某種儲存介質上劃出一片空間,賦給其中一個程式寫的權利,另一個程式讀的權利即可。

管道

從根本上來說,管道是一個線性位元組陣列,類似檔案,可以使用檔案讀寫的方式進行訪問。但是卻不是檔案。

在程式建立管道需使用系統呼叫popen()或者pipe(),這是兩種不同的方法,使用時的引數什麼的肯定也是不同

popen():建立管道需要使用系統呼叫,需要提供一個目標程式作為引數(注意不是目標程式名字),然後在呼叫該函式的程式和給出的目標程式之間建立一個管道。因此就像打電話 一樣,必須要知道對方的號碼才能實現通訊。
建立時還需要一個參數列明管道型別:讀管道還是寫管道。

pipe():將返回兩個檔案描述符,其中一個用來管道進行讀操作,一個用於寫入管道。pipe()將兩個檔案描述符連線起來,使得一端可以讀,一端可以寫。

管道的重要特點是:使用管道的兩個程式之間必須存在某種關係,popen必須提供目標程式的檔名,pipe兩個程式必須隸屬於父子程式

記名管道

上面的管道使用的時候兩個程式之間必須要存在某種關係,但是如果要在兩個不相關的程式之間進行管道通訊就需要使用記名管道,記名管道與檔案系統共享一個名稱空間,因此我們可以從檔案系統中看到記名管道。也就是說,記名管道的名字不能和檔名重複。

一個程式建立一個記名管道後,另外一個程式可以使用Open來開啟這個管道,從而與另外一端進行通訊。

管道和記名管道不是在所有系統上都是支援的,主要支援這兩種方式的是UNIX和類UNIX的作業系統,其次是無名管道要在相關程式上通訊,記名管道需要知道對方的名字,在某種場合上也不是很方便

蟲洞:套接字

套接字(socket)是另一種可以用於程式間通訊的機制。可以支援不同層面,不同應用,跨網路的通訊。

使用套接字進行通訊的雙方都需要一個套接字,一個服務費那個,一個客戶方

服務方的套接字既不傳送資料也不接受資料,僅僅是產生一個與客戶套接字對接的套接字


  • 套接字


  • 本地套接字
  • 網路套接字

  • 資料流套接字(stream socket):提供雙向,有序,可靠,非重複資料通訊
  • 電報流套接字(datastream socket):提供雙向訊息流。資料不一定按序到達
  • 序列包套接字(sequential socket):提供雙向,有序,可靠連線,包有最大限制
  • 裸套接字(raw socket):提供對下層通訊協議的訪問

程式電報:訊號

又是上述方式的優化,先說上述方式的缺點:管道和套接字雖然提供了豐富的通訊語義,但是必須事先在通訊的程式間建立連線,需要消耗系統資源。其次,通訊是自願的,可以選擇是否同意通訊,就是一廂情願的那個意思。另外,我們要通訊的資訊量較小,使用管道和套接字開銷相對來說是入不敷出,實在是大材小用了。
新的機制:

  • 迫使對方對我們的通訊做出立即回應
  • 不想事先建立任何連線,而是臨時突然覺得需要與某個程式進行通訊
  • 傳輸的資訊量小,使用管道或套接字不划算。

於是發明了訊號(singal)機制
訊號是一個核心物件或者說是一個核心資料結構。傳送方將資料結構的內容填好並註明目標程式後,發出特定的軟體中斷。作業系統接收到的特定中斷請求後,到特定的資料結構中查詢訊號接收方,並進行通知,接到通知的程式對訊號進行處理。完全就是一個快遞的操作流程

程式旗語:訊號量

在單軌道的火車場景中可以使用:火車看訊號牌是否允許進入軌道。在計算機中,訊號量實際上就是一個簡單的整數

程式擁抱:共享程式

愛人要擁抱才更親密,才能盡情的共享。要使用共享記憶體進行通訊,一個程式首先要建立一片記憶體空間專門為通訊用。而其他程式則將該片記憶體對映到自己的虛擬地址空間。讀寫自己的空間對應共享記憶體的區域時,就是在和其他程式通訊

共享記憶體機制的兩個程式必須在同一物理機器上,共享記憶體的訪問方式是隨機的而不是隻能從一端讀,另一端寫

缺點也是在這裡管理複雜,還必須在同一臺物理機器上才能使用,安全性也脆,可以互相傳染。

使用全域性變數在同一個程式的程式間實現通訊不稱為共享記憶體

信件傳送:訊息佇列

  • 無需固定的讀寫程式,任何程式都可以讀寫(當然是有許可權的程式)
  • 可以同時支援多個程式,多個程式可以同時讀寫訊息佇列,多對多
  • 只在記憶體中實現
  • 並不只是在UNIX和類UNIX上實現,幾乎所有的主流作業系統都支援訊息佇列

其他通訊機制

除了上述的主流通訊方式,一些作業系統還提供了一些其特有的通訊機制。

  • Windows:剪貼簿(clipboard).COM/DCOM,動態資料交換(DDE),郵箱(mailslots);

相關文章