作業系統核心原理-3.程序原理(下):程序通訊
程序作為人類的發明,自然也免不了脫離人類的習性,也有通訊的需求。如果程序之間不進行任何通訊,那麼程序所能完成的任務就要大打折扣。人類的通訊方式無外乎對白(通過聲音溝通)、打手勢、寫信、發電報、擁抱等方法。同理,程序也可以通過同樣的方式來進行通訊。本篇我們就來看看程序的這些互動方式。
一、程序對白:管道、套接字
人們最常用的通訊手段就是對白,一方發出聲音,另一方接收聲音。而聲音的傳遞需要通過一些介質,例如:空氣(face to face)、線纜(有線電話)等。類似的,程序對白就是一個程序發出某種資料資訊,另外一方接收資料資訊,而這些資料資訊通過一片共享的儲存空間進行傳遞。
1.1 管道
一個程序向儲存空間的一端寫入資訊,另一個程序儲存空間的另外一端讀取資訊,這個就是管道。就像兩個人對白的媒介是空氣也可以是線纜一樣,管道所佔的空間既可以是記憶體也可以是磁碟。
要建立一個管道,一個程序只需要呼叫管道建立的系統呼叫即可,該系統呼叫所做的事情就是在某種儲存介質上劃出一片空間,賦給其中一個程序寫的權利,另一個程序讀的權利即可。
例如在Linux下,我們通過Shell命令輸入兩個命令,中間通過符號“|”來建立兩個命令之間的管道:
$ sort < file1 | grep zou
上面一個命令表示:對file1的內容首先進行排序,排序完成後的結果將作為grep的輸入,在結果裡面找出所有包括字串zou的文字行。也就是說,在兩個任務“排序“(sort)和”查詢”(grep)之間建立了一個管道,資料從sort流向了grep。
1.2 套接字
套接字(Socket)的功能非常強大,可以支援不同層面、不同應用、跨網路的通訊。使用套接字進行通訊需要雙方均建立一個套接字,其中一方作為伺服器方,另外一方作為客戶方。伺服器方必須首先建立一個服務區套接字,然後在該套接字上進行監聽,等待遠方的連線請求。客戶方也要建立一個套接字,然後向伺服器方傳送連線請求。伺服器套接字在受到連線請求之後,將在伺服器方機器上新建一個客戶套接字,與遠方的客戶方套接字形成點到點的通訊通道。之後,客戶方和伺服器方便可以直接通過類似於send和recv的命令在這個建立的套接字管道上進行交流了。
例如,在C#中我們可以輕鬆地建立一個伺服器方的Socket:
// 建立Socket->繫結IP與埠->設定監聽佇列的長度->開啟監聽連線 socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socketWatch.Bind(new IPEndPoint(IPAddress.Parse(txtIPAddress.Text), int.Parse(txtPort.Text))); socketWatch.Listen(10);
1.3 不足之處
(1)必須首先在通訊的程序間建立連線(管道或套接字),這需要消耗系統資源;
(2)通訊是自願的,而管道和套接字需要強制雙方進行通訊;
(3)由於建立連線需要消耗時間,一旦建立就應該儘可能多的通訊,如果通訊資訊量很小,則就是“殺雞用牛刀”了;
二、程序電報與旗語:訊號與訊號量
2.1 電報:訊號
訊號類似於我們生活中的電報,如果你想給某人發一封電報,就擬好電文,然後將報文和收報人的資訊都交給電報公司。電報公司則將電報傳送到收報人所在地的郵局,並通知收報人來取電報。其中,發報文時無需收報人實現知道,也無需進行任何協調。如果對方選擇不對訊號做出響應,則將被OS終止執行。
在計算機中,訊號就是一個核心物件或者是一個核心資料結構。傳送方將該資料結構的內容填好,並指明該訊號的目標程序後,發出特定的軟體中斷(這就是一個發電報的操作)。OS接收到特定的中斷請求後,知道是有程序要傳送訊號,於是到特定的核心資料結構裡查詢訊號接收方,並進行通知。接到通知的程序則對訊號進行相應處理。
2.2 旗語:訊號量
訊號量來源於鐵路的執行:在一條單軌鐵路上,任何時候只允許有一列火車行駛在該鐵路上,而管理這條鐵路的系統就是訊號量。任何一列火車必須等到表明該鐵路可以行駛的訊號後才能進入軌道。當列車進入後,需要將訊號改為禁止狀態進入來防止別的列車同時進入。而當列車駛出單軌後,則需要將訊號變回允許進入狀態,這很像以前的旗語。當然,通過聯想到我們實際開發中經常用的鎖,這就更容易理解了。
在計算機中,訊號量實際上就是一個簡單整數。一個程序在訊號變為0或1的情況下推進,並將訊號變為1或0來防止別的程序同時推進。當該程序完成任務後,則將訊號再改為0或1,從而允許其他程序執行。從而我們也可以看出,訊號量已經不只是一種通訊機制,更是一種同步機制。
三、程序擁抱:共享記憶體
前面通過對話、發電報、旗語已經滿足了多種通訊需要,但是當兩個程序要共享大量資料時就沒法十分滿足需求。就如同兩個墜入愛河的騷年,它們互相喜歡並想要在一起同居(共享大量資料),這時打電話、發電報、握手對話就顯得不夠了。這時候,它們需要的就是擁抱,只有緊緊擁抱才能儘可能地共享,feeling so good!
3.1 共享記憶體
程序的擁抱就是共享記憶體,兩個程序共同擁有同一片記憶體。對於這片記憶體中的任何內容,二者均可以訪問。要使用共享記憶體進行通訊,程序A首先需要建立一片記憶體空間作為通訊用,而其他程序B則將片記憶體對映到自己的(虛擬)地址空間。這樣,程序A讀寫自己地址空間中對應共享記憶體的區域時,就是在和程序B進行通訊。
3.2 不足之處
(1)使用共享記憶體機制通訊的兩個程序必須在同一臺物理機上;
(2)安全性脆弱,假如一個程序有病毒,會很容易傳給另外一個程序;
四、信件傳送:訊息佇列
訊息佇列是一列具有頭和尾的訊息排列,新來的訊息放在佇列尾部,而讀取訊息則從佇列頭部開始,如下圖所示:
這樣看來,它和管道十分類似,一頭讀,一頭寫?的確,看起來很像管道,但又不是管道:
(1)訊息佇列無固定的讀寫程序,任何程序都可以讀寫;而管道需要指定誰讀和誰寫;
(2)訊息佇列可以同時支援多個程序,多個程序可以讀寫訊息佇列;即所謂的多對多,而管道是點對點;
(3)訊息佇列只在記憶體中實現,而管道還可以在磁碟上實現;
參考資料
鄒恆明,《作業系統之哲學原理》,機械工業出版社
作者:周旭龍
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連結。
相關推薦
作業系統核心原理-3.程序原理(下):程序通訊
程序作為人類的發明,自然也免不了脫離人類的習性,也有通訊的需求。如果程序之間不進行任何通訊,那麼程序所能完成的任務就要大打折扣。人類的通訊方式無外乎對白(通過聲音溝通)、打手勢、寫信、發電報、擁抱等方法。同理,程序也可以通過同樣的方式來進行通訊。本篇我們就來看看程序的這些互動方式。 一、程序對白:管道、
作業系統核心原理-5.記憶體管理(下):段式記憶體管理
一、分頁系統的缺點 分頁系統存在的一個無法容忍,同時也是分頁系統無法解決的一個缺點就是:一個程序只能佔有一個虛擬地址空間。在此種限制下,一個程式的大小至多隻能和虛擬空間一樣大,其所有內容都必須從這個共同的虛擬空間內分配。 二、分段管理系統 2.1 何為分段管理 分段管理就是將一個程式按照邏輯單
作業系統核心原理-3.程序原理(中):程序排程
PS:在多程序併發的環境裡,雖然從概念上看,有多個程序在同時執行,但在單個CPU下,在任何時刻只能有一個程序處於執行狀態,而其他程序則處於非執行狀態。那麼問題來了,我們是如何確定在任意時刻到底由哪個程序執行,哪些不執行呢?這就涉及到程序管理的一個重要組成部分:程序排程,跟隨本篇來一起復習下程序排程吧! 一、
作業系統核心原理-4.執行緒原理(下):死鎖基礎原理
我們都見過交通阻塞,一大堆汽車因為爭奪行路權,互不相讓而造成阻塞,又或者因為車輛發生故障拋錨或兩輛車相撞而造成道路阻塞。在這種情況下,所有的車都停下來,誰也無法前行,這就是死鎖。本篇就來了解一下什麼是死鎖,如何應對死鎖。 一、死鎖初窺 1.1 為何會發生死鎖? 死鎖的發生歸根結底是因為對資源的競
作業系統核心原理-6.外存管理(下)檔案系統
一、為何需要檔案系統? 磁碟具有大容量、低成本以及持久化的特點,即使發生斷電,磁碟上的資料也不會丟失。但是,對於一般使用者而言,使用磁碟是非常苦難的,因為他們不知道如何驅動一個磁碟,以及計算資料在磁碟上的存放位置。從上一篇《磁碟基礎》可以知道,瞭解磁碟的各項技術細節將使使用者不堪重負。 作業系統是
作業系統核心原理-5.記憶體管理(中):分頁記憶體管理
在上一篇介紹的幾種多道程式設計的記憶體管理模式中,以交換記憶體管理最為靈活和先進。但是這種策略也存在很多重大問題,而其中最重要的兩個問題就是空間浪費和程式大小受限。那麼有什麼辦法可以解決交換記憶體存在的這些問題呢?答案是分頁,它是我們解決交換缺陷的“不二法門”。 一、分頁記憶體管理 1.1 解決問題之
作業系統核心原理-5.記憶體管理(上):基本記憶體管理
作業系統的兩個角色分別是魔術師和管理者,在管理者這個角色中,除了CPU之外,記憶體是作業系統要管理的另外一個重要資源。記憶體管理需要達到兩個目標:一是地址保護,即一個程式不能訪問另一個程式的地址空間。二是地址獨立,即程式發出的地址應該與物理主存地址無關。這兩個目標就是衡量一個記憶體管理系統是否完善的標準,
ORCAD16.6中原理圖DRC檢查(下)
Cadence Orcad DRC 檢查 接ORCAD16.6中原理圖DRC檢查(上) 上次說了電氣規則,下面接著說物理規則。 參考了http://blog.sina.com.cn/s/blog_e0ae98f10101fhg1.html; 5、物理規則 check power pin vi
每天3分鐘作業系統修煉祕籍(17):程序間通訊(3):套接字
點我檢視祕籍連載 套接字 套接字(Socket)用於協調不同計算機上的程序間通訊,也就是基於網路的通訊。當然,也可以在本機上使用套接字進行程序間的通訊。 套接字通訊的方式非常多,有Unix域套接字、TCP套接字、UDP套接字、鏈路層套接字等等。但最常用的肯定是TCP套接字。所以,這裡介紹下TCP Socket
每天3分鐘作業系統修煉祕籍(24):程序狀態以及狀態轉換
點我檢視祕籍連載 程序狀態以及狀態轉換 程序並非總是處於執行中,例如CPU沒執行在它身上時它就是非執行的。程序在建立之後會改變狀態,不同的狀態之間可以實現狀態切換,可以通過ps或top等命令捕獲程序的狀態。包含以下幾種狀態: 建立態(new):程序正在被建立中,過程非常短暫,使用者無法捕捉 執行態(run
每天3分鐘作業系統修煉祕籍(25):程序排程演算法圖解說明
點我檢視祕籍連載 程序排程 在這裡簡單介紹一些程序排程相關的演算法策略,雖然瞭解這些對於使用Linux來說不會有很大幫助,但是卻能幫助我們瞭解程序排程追求的是什麼,它和生活中的很多案例都類似。 程序排程的兩個關鍵性指標是:響應時間和週轉時間。 響應時間:程序未執行到下次被選中執行的時間間隔。例如程序剛被建立
計算機網路3——傳輸層(下)
目錄 六、面向連線傳輸協議TCP 1、TCP可靠資料傳輸 2、TCP流量控制 3、TCP連線管
Spring原始碼解析--《SPRING技術內幕:深入解析Spring架構與設計原理》讀書筆記(一):IOC容器初始化過程
通過閱讀相關章節內容,Spring中IOC容器的載入中,我們需要了解下列幾個概念: Resource:是一個定位、訪問資源的抽象介面,包含了多種資源操作的基礎方法定義,如getInputStream()、exists()、isOpen()、getD
SVM全系列:從原理到python實現(一):SVM原理
前言 本文開始主要介紹一下SVM的分類原理以及SVM的數學匯出和SVM在Python上的實現。借鑑了許多文章,會在後面一一指出,如果有什麼不對的希望能指正。 一、 SVM簡介 首先看到SVM是在斯坦福的機器學習課程上,SVM是作為分類器在logisticregr
Android系統原理與原始碼分析(1):利用Java反射技術阻止通過按鈕關閉對話方塊
本文為原創,如需轉載,請註明作者和出處,謝謝! 眾所周知,AlertDialog類用於顯示對話方塊。關於AlertDialog的基本用法在這裡就不詳細介紹了,網上有很多,讀者可以自己搜尋。那
探索ASP.NET MVC5系列之~~~3.檢視篇(下)---包含常用表單和暴力解猜防禦
其實任何資料裡面的任何知識點都無所謂,都是不重要的,重要的是學習方法,自行摸索的過程(不妥之處歡迎指正) 這幾天忙著幫別人普及安全,今天就把這篇文章結束掉,明天講下 “過度提交” 的防禦。這次開篇就激烈點==》爆破演示: 開啟Burp 設定監聽埠==》8080 設定一下代理:
uC/OS 的程序排程(下)
上文提到uC/OS程序排程的前兩個主題:何時進行排程、如何選擇下一個活動程序。本文來分析最後一個主題,即如何實現程序切換。 從上文的分析可知,uC/OS在實現排程時,涉及的最核心的函式只有三個:OSStartHighRdy()、OS_Sched()及OSInt
Linux核心分析(六):程序的描述和程序的建立
一、Linux中的程序簡析 程序是具有多道程式設計的作業系統的基本概念,關於程序的定義就是程式執行的一個例項,也是系統資源排程的最小單位。如果同一個程式被多個使用者同時執行,那麼這個程式就有多個相對獨立的程序,與此同時他們又共享相同的執行程式碼。在Li
我是如何學習寫一個作業系統(六):程序的排程
前言 既然引進了多程序,其實也就是在程序之間來回切換,那麼就會有程序之間的排程問題。實則是在可執行程序之間分配有限的處理器時間資源的核心子系統。 幾個簡單的CPU排程演算法 First Come, First Served(FCFS) 其實就是一個先進先出隊列了,也就是說先申請的程序,先執行。當CPU空閒
我是如何學習寫一個作業系統(七):程序的同步與訊號量
前言 在多程序的執行環境下,程序是併發執行的,不同程序間存在著不同的相互制約關係。為了協調程序之間的相互制約關係,達到資源共享和程序協作,避免程序之間的衝突,引入了程序同步的概念。 臨界資源 多個程序可以共享系統中的各種資源,但其中許多資源一次只能為一個程序所使用,我們把一次只允許一個程序使用的資源成為臨界資