1、作業系統的邏輯結構
1.1、邏輯結構的概念
邏輯結構就是 OS 的設計和實作思路。
1.2、邏輯結構分類
- 整體式結構
- 層次式結構
- 微核心結構(客戶/伺服器結構,Client/Server)
1、整體式結構
整體式結構以子產品為機關,子產品之間互相調用。
特點
- 子產品設計、編碼和調試獨立。
- 子產品調用自由。
- 子產品通信多以全局變量形式完成。
缺點
- 資訊傳遞随意,維護和更新困難。
2、層次式結構
例如:TCP/IP協定。
所有的功能子產品按照次序排成若幹層,相鄰層單向依賴或單向調用。
分層原則
- 硬體相關-最底層。
- 外部特性-最外層。
- 中間層-調用次序或消息傳遞順序.。
- 共性的服務-較低層。
- 活躍功能-較低層.
層次結構的優點
- 結構清晰,避免循環調用。
- 整體問題局部化,系統的正确性容易保證。
- 有利于作業系統的維護、擴充、移植。
3、微核心結構(客戶/伺服器結構,Client/Server)
作業系統=微核心+核外伺服器。
- 微核心
足夠小,提供OS最基本的核心功能和服務。
1、實作與硬體緊密相關的處理。
2、實作一些較基本的功能。
3、負責客戶和伺服器間的通信。
- 核外伺服器
完成OS的絕大部分服務功能,等待應用程式提出請求由若幹伺服器或程序共同構成;
例如:程序/線程伺服器、虛存伺服器、裝置管理伺服器等 以程序形式運作在使用者态。
執行個體
2、CPU的态
2.1、概念
- CPU的工作狀态。
- 對資源和指令使用權限的概述。
2.2、态的分類
- 核态(Kernel mode)
能夠通路所有資源和執行所有的指令;管理程式/os核心。
- 使用者态(User node,目态)
僅能通路部分資源,其他資源受限;管理使用者程式。
- 管态(Supervisor mode)
介于核态和使用者态之間。
管态界限比較模糊,我們一般讨論使用者态和核态之間的轉換。
2.3、使用者态與核态之間的轉化
- 使用者态向核态轉化。
使用者請求OS提供服務;
發生中斷;
使用者程序産生錯誤(内部中斷);
使用者态企圖執行特權指令;
- 核态向使用者态轉化
一般是執行中斷傳回:IRET。
使用者态向核心态轉有多種情形(使用者請求OS提供服務、發生中斷、使用者程序産生錯誤、使用者态企圖執行特權指令),但是本質上就是一種情形,即通過中斷的形式進入。
系統調用、異常、外圍裝置的中斷是系統在運作時由使用者态轉到核心态的最主要的3種方式,其中系統調用的本質其實也是中斷,相對于外圍裝置的硬中斷,這種中斷稱為軟中斷,這是作業系統為使用者特别開放的一種中斷。是以,從觸發方式和效果上來看,這三種切換方式是完全一樣的,都相當于是執行了一個中斷響應的過程。但是從觸發的對象來看,系統調用是程序主動請求切換的,而異常和硬中斷則是被動的。
2.4、硬體和OS對CPU的觀察
- 硬體按照“态“來區分CPU的狀态。
- OS按照“程序”來區分CPU的狀态。
2.5、英特爾cpu的态
如圖,分為三層,從内到外,權限降低。
3、分時存儲系統
3.1、存儲器
3.2、分時存儲系統的工作原理
命中,則直接從Cache裡面讀取指令,資料;如果沒有命中,則先會找主存,如果還沒有命中,則會導緻通路缺頁,即去找輔存。
4、中斷機制
4.1、什麼是中斷機制
中斷機制是現代計算機系統中的基本機制之一,它在系統中起着通信網絡的作用,以協調系統對各種外部事件的響應和處理,中斷是實作多道程式設計的必要條件,中斷是CPU 對系統發生的某個事件作出的一種反應。
- 引起中斷的事件稱為中斷源。
- 中斷源向CPU 提出處理的請求稱為中斷請求。
- 發生中斷時被打斷程式的暫停點稱為斷點。
- CPU暫停現行程式而轉為響應中斷請求的過程稱為中斷響應。
- 進行中斷源的程式稱為中斷處理程式。
- CPU執行有關的中斷處理程式稱為中斷處理。
- 而傳回斷點的過程稱為中斷傳回。中斷的實作由軟體和硬體綜合完成,硬體部分叫做硬體裝置,軟體部分稱為軟體處理程式。
中斷機制包括硬體的中斷裝置和作業系統的中斷處理服務程式。
中斷的一個例子:
在你敲打鍵盤的時候,鍵盤控制器(控制鍵盤的硬體裝置)會發送一個中斷,通知作業系統有鍵按下。中斷本質是一種特殊的電信号,由硬體裝置發向處理器。處理器接受到中斷後,會馬上向作業系統反映此信号的到來,然後就由os負責處理這些新到來的資料。硬體裝置生成中斷的時候并不考慮與處理器的時鐘同步——換句話說就是中斷随時可以産生。是以,核心随時可能因為新到來的中斷而被打斷。
4.2、中斷的一些概念
4.3、中斷的響應過程
4.4、中斷的本質(對比中斷和輪詢)
雖然人們在談到中斷(Interrupt)時,總會拿輪詢(Polling)來做“反面”例子,但中斷和輪詢并不是完全對立的兩個概念,它們是對立統一的。
“CPU執行完每條指令時,都會去檢查一個中斷标志位”,這句話是所有關于中斷長篇大論的開場白,但很容易被人忽略,其實,這就是中斷的本質。
舉個例子,CPU老闆是一家公司的光杆司令,所有的顧客都要他親自跑去處理,還要跟有關部門打點關系,CPU覺得顧客和公關這兩樣事它一個人搞不來,這就是輪詢;終于這家公司更新發展了,CPU老闆請了一個秘書,所有的顧客都先由秘書經手,CPU心情好的時候就去看一下,大部分時間都忙着去公關了,這時它覺得輕松了很多,這就是中斷了~~
也就是說,中斷和輪詢是從CPU老闆的角度來看的,不管怎樣,事件都還是有人來時刻跟蹤才能被捕獲處理,不過是老闆還是秘書的問題。所有的中斷(或者異步,回調等)背後都有一個輪詢(循環,listener)。
5、CPU的上下文切換
我們都知道,Linux 是一個多任務作業系統,它支援遠大于 CPU 數量的任務同時運作。當然,這些任務實際上并不是真的在同時運作,而是因為系統在很短的時間内,将 CPU 輪流配置設定給它們,造成多任務同時運作的錯覺。
而在每個任務運作前,CPU 都需要知道任務從哪裡加載、又從哪裡開始運作,也就是說,需要系統事先幫它設定好CPU 寄存器和程式計數器。
5.1、什麼是 CPU 上下文
CPU 寄存器和程式計數器就是 CPU 上下文,因為它們都是 CPU 在運作任何任務前,必須的依賴環境。
- CPU 寄存器是 CPU 内置的容量小、但速度極快的記憶體。
- 程式計數器則是用來存儲 CPU 正在執行的指令位置、或者即将執行的下一條指令位置。
什麼是 CPU 上下文切換
就是先把前一個任務的 CPU 上下文(也就是 CPU 寄存器和程式計數器)儲存起來,然後加載新任務的上下文到這些寄存器和程式計數器,最後再跳轉到程式計數器所指的新位置,運作新任務。
而這些儲存下來的上下文,會存儲在系統核心中,并在任務重新排程執行時再次加載進來。這樣就能保證任務原來的狀态不受影響,讓任務看起來還是連續運作。
5.2、CPU 上下文切換的類型
根據任務的不同,可以分為以下三種類型
- 程序上下文切換。
- 線程上下文切換。
- 中斷上下文切換。
程序上下文切換
Linux 按照特權等級,把程序的運作空間分為核心空間和使用者空間,分别對應着下圖中, CPU 特權等級的 Ring 0 和 Ring 3。
- 核心空間(Ring 0)具有最高權限,可以直接通路所有資源。
- 使用者空間(Ring 3)隻能通路受限資源,不能直接通路記憶體等硬體裝置,必須通過系統調用陷入到核心中,才能通路這些特權資源。
程序既可以在使用者空間運作,又可以在核心空間中運作。程序在使用者空間運作時,被稱為程序的使用者态,而陷入核心空間的時候,被稱為程序的核心态。
5.3、系統調用
從使用者态到核心态的轉變,需要通過系統調用來完成。比如,當我們檢視檔案内容時,就需要多次系統調用來完成:首先調用 open() 打開檔案,然後調用 read() 讀取檔案内容,并調用 write() 将内容寫到标準輸出,最後再調用 close() 關閉檔案。
在這個過程中就發生了 CPU 上下文切換,整個過程是這樣的:
- 1、儲存 CPU 寄存器裡原來使用者态的指令位。
- 2、為了執行核心态代碼,CPU 寄存器需要更新為核心态指令的新位置。
- 3、跳轉到核心态運作核心任務。
- 4、當系統調用結束後,CPU 寄存器需要恢複原來儲存的使用者态,然後再切換到使用者空間,繼續運作程序。
是以,一次系統調用的過程,其實是發生了兩次 CPU 上下文切換。(使用者态-核心态-使用者态)。
不過,需要注意的是,系統調用過程中,并不會涉及到虛拟記憶體等程序使用者态的資源,也不會切換程序。這跟我們通常所說的程序上下文切換是不一樣的:程序上下文切換,是指從一個程序切換到另一個程序運作;而系統調用過程中一直是同一個程序在運作。
是以,系統調用過程通常稱為特權模式切換,而不是上下文切換。系統調用屬于同程序内的 CPU 上下文切換。但實際上,系統調用過程中,CPU 的上下文切換還是無法避免的。
程序上下文切換跟系統調用又有什麼差別呢
首先,程序是由核心來管理和排程的,程序的切換隻能發生在核心态。是以,程序的上下文不僅包括了虛拟記憶體、棧、全局變量等使用者空間的資源,還包括了核心堆棧、寄存器等核心空間的狀态。
是以,程序的上下文切換就比系統調用時多了一步:在儲存核心态資源(目前程序的核心狀态和 CPU 寄存器)之前,需要先把該程序的使用者态資源(虛拟記憶體、棧等)儲存下來;而加載了下一程序的核心态後,還需要重新整理程序的虛拟記憶體和使用者棧。
如下圖所示,儲存上下文和恢複上下文的過程并不是“免費”的,需要核心在 CPU 上運作才能完成。
5.4、程序上下文切換潛在的性能問題
根據 Tsuna 的測試報告,每次上下文切換都需要幾十納秒到數微秒的 CPU 時間。這個時間還是相當可觀的,特别是在程序上下文切換次數較多的情況下,很容易導緻 CPU 将大量時間耗費在寄存器、核心棧以及虛拟記憶體等資源的儲存和恢複上,進而大大縮短了真正運作程序的時間。這也正是導緻平均負載升高的一個重要因素。
另外,我們知道, Linux 通過 TLB(Translation Lookaside Buffer)來管理虛拟記憶體到實體記憶體的映射關系。當虛拟記憶體更新後,TLB 也需要重新整理,記憶體的通路也會随之變慢。特别是在多處理器系統上,緩存是被多個處理器共享的,重新整理緩存不僅會影響目前處理器的程序,還會影響共享緩存的其他處理器的程序。
5.5、發生程序上下文切換的場景
- 為了保證所有程序可以得到公平排程,CPU 時間被劃分為一段段的時間片,這些時間片再被輪流配置設定給各個程序。這樣,當某個程序的時間片耗盡了,就會被系統挂起,切換到其它正在等待 CPU 的程序運作。
- 程序在系統資源不足(比如記憶體不足)時,要等到資源滿足後才可以運作,這個時候程序也會被挂起,并由系統排程其他程序運作。
- 當程序通過睡眠函數 sleep 這樣的方法将自己主動挂起時,自然也會重新排程。
- 當有優先級更高的程序運作時,為了保證高優先級程序的運作,目前程序會被挂起,由高優先級程序來運作。
- 發生硬體中斷時,CPU 上的程序會被中斷挂起,轉而執行核心中的中斷服務程式。
5.6、線程上下文切換
線程與程序最大的差別在于:線程是排程的基本機關,而程序則是資源擁有的基本機關。說白了,所謂核心中的任務排程,實際上的排程對象是線程;而程序隻是給線程提供了虛拟記憶體、全局變量等資源。
是以,對于線程和程序,我們可以這麼了解: - 當程序隻有一個線程時,可以認為程序就等于線程。 - 當程序擁有多個線程時,這些線程會共享相同的虛拟記憶體和全局變量等資源。這些資源在上下文切換時是不需要修改的。 - 另外,線程也有自己的私有資料,比如棧和寄存器等,這些在上下文切換時也是需要儲存的。
發生線程上下文切換的場景
- 前後兩個線程屬于不同程序。此時,因為資源不共享,是以切換過程就跟程序上下文切換是一樣。
- 前後兩個線程屬于同一個程序。此時,因為虛拟記憶體是共享的,是以在切換時,虛拟記憶體這些資源就保持不動,隻需要切換線程的私有資料、寄存器等不共享的資料。
5.7、中斷上下文切換
為了快速響應硬體的事件,中斷處理會打斷程序的正常排程和執行,轉而調用中斷處理程式,響應裝置事件。而在打斷其他程序時,就需要将程序目前的狀态儲存下來,這樣在中斷結束後,程序仍然可以從原來的狀态恢複運作。
跟程序上下文不同,中斷上下文切換并不涉及到程序的使用者态。是以,即便中斷過程打斷了一個正處在使用者态的程序,也不需要儲存和恢複這個程序的虛拟記憶體、全局變量等使用者态資源。中斷上下文,其實隻包括核心态中斷服務程式執行所必需的狀态,包括 CPU 寄存器、核心堆棧、硬體中斷參數等。
對同一個 CPU 來說,中斷處理比程序擁有更高的優先級,是以中斷上下文切換并不會與程序上下文切換同時發生。同樣道理,由于中斷會打斷正常程序的排程和執行,是以大部分中斷處理程式都短小精悍,以便盡可能快的執行結束。
另外,跟程序上下文切換一樣,中斷上下文切換也需要消耗 CPU,切換次數過多也會耗費大量的 CPU,甚至嚴重降低系統的整體性能。是以,當你發現中斷次數過多時,就需要注意去排查它是否會給你的系統帶來嚴重的性能問題。
文章來源:https://blog.csdn.net/qq_44861675/article/details/107736922